feat: Simplify watchlist functionality and add table creation checks

This commit is contained in:
Bobby (aider) 2025-02-17 16:43:24 -08:00
parent a6d7a3fb54
commit 579f870c08
2 changed files with 93 additions and 137 deletions

View File

@ -227,42 +227,41 @@ def trading_system_page():
# Move Add to Watch List button outside of columns # Move Add to Watch List button outside of columns
if st.button("Add to Watch List", key="add_to_watchlist"): if st.button("Add to Watch List", key="add_to_watchlist"):
try: try:
# Create a container for debug output # Ensure tables exist
debug_container = st.container() ensure_tables_exist()
with debug_container:
st.write("=== PRE-WATCHLIST ITEM CREATION ===")
st.json({
"Ticker": ticker,
"Entry Price": entry_price,
"Target Price": target_price,
"Stop Loss": position['stop_loss'],
"Notes": notes,
"Selected Watchlist ID": selected_list[0]
})
item = WatchlistItem( # Create watchlist item
ticker=ticker, item = WatchlistItem(
entry_price=float(entry_price), ticker=ticker,
target_price=float(target_price), entry_price=float(entry_price),
stop_loss=float(position['stop_loss']), target_price=float(target_price),
notes=str(notes) if notes else '' stop_loss=float(position['stop_loss']),
) notes=str(notes) if notes else ''
)
st.write("=== WATCHLIST ITEM DETAILS ===") # Show debug information
st.json(vars(item)) st.write("Adding item to watchlist:", {
"watchlist_id": selected_list[0],
"ticker": item.ticker,
"entry_price": item.entry_price,
"target_price": item.target_price,
"stop_loss": item.stop_loss,
"notes": item.notes
})
success = add_to_watchlist(selected_list[0], item) # Add to watchlist
success = add_to_watchlist(selected_list[0], item)
if success: if success:
st.success(f"Added {ticker} to watch list!") st.success(f"Added {ticker} to watchlist!")
time.sleep(3) # Give time to see success message time.sleep(2)
st.experimental_rerun() st.experimental_rerun()
else: else:
st.error("Failed to add to watch list. Check the details above.") st.error("Failed to add to watchlist")
except Exception as e: except Exception as e:
st.error(f"Error adding to watchlist: {str(e)}") st.error(f"Error: {str(e)}")
logger.exception("Error in watchlist addition") logger.exception("Error adding to watchlist")
except Exception as e: except Exception as e:
st.error(f"Error calculating position: {str(e)}") st.error(f"Error calculating position: {str(e)}")

View File

@ -9,6 +9,36 @@ import time
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def ensure_tables_exist():
with create_client() as client:
# Create watchlists table if not exists
client.command("""
CREATE TABLE IF NOT EXISTS stock_db.watchlists (
id UInt32,
name String,
strategy String,
created_at DateTime
)
ENGINE = MergeTree()
ORDER BY (id)
""")
# Create watchlist_items table if not exists
client.command("""
CREATE TABLE IF NOT EXISTS stock_db.watchlist_items (
id UInt32,
watchlist_id UInt32,
ticker String,
entry_price Float64,
target_price Float64,
stop_loss Float64,
notes String,
created_at DateTime
)
ENGINE = MergeTree()
ORDER BY (id)
""")
@dataclass @dataclass
class WatchlistItem: class WatchlistItem:
ticker: str ticker: str
@ -39,115 +69,42 @@ def get_watchlists() -> List[dict]:
def add_to_watchlist(watchlist_id: int, item: WatchlistItem) -> bool: def add_to_watchlist(watchlist_id: int, item: WatchlistItem) -> bool:
with create_client() as client: with create_client() as client:
try: try:
# Debug output using both logger and st.write # Get next ID
debug_msg = f""" result = client.query("SELECT max(id) + 1 as next_id FROM stock_db.watchlist_items")
=== WATCHLIST INSERT ATTEMPT === next_id = result.first_row[0] if result.first_row[0] is not None else 1
Watchlist ID: {watchlist_id}
Item details:
- Ticker: {item.ticker}
- Entry Price: {item.entry_price}
- Target Price: {item.target_price}
- Stop Loss: {item.stop_loss}
- Notes: {item.notes}
==============================
"""
logger.info(debug_msg)
st.code(debug_msg) # Using st.code for better formatting
# Force a container to stay visible # Insert the item
placeholder = st.empty() data = [(
with placeholder.container(): next_id,
# Check if watchlist exists watchlist_id,
check_watchlist_query = f"SELECT * FROM stock_db.watchlists WHERE id = {watchlist_id}" item.ticker,
watchlist_result = client.query(check_watchlist_query) item.entry_price,
logger.info(f"Watchlist check result: {watchlist_result.result_rows}") item.target_price,
st.write("Watchlist check result:", watchlist_result.result_rows) item.stop_loss,
item.notes or '',
datetime.now()
)]
if not watchlist_result.result_rows: client.insert(
error_msg = f"Watchlist ID {watchlist_id} not found" 'stock_db.watchlist_items',
logger.error(error_msg) data,
st.error(error_msg) column_names=[
return False
# Get next ID
id_query = "SELECT max(id) + 1 as next_id FROM stock_db.watchlist_items"
result = client.query(id_query)
next_id = result.first_row[0] if result.first_row[0] is not None else 1
logger.info(f"Next ID: {next_id}")
st.write(f"Next ID: {next_id}")
# Prepare data
data = [(
int(next_id),
int(watchlist_id),
str(item.ticker),
float(item.entry_price),
float(item.target_price),
float(item.stop_loss),
str(item.notes or ''),
datetime.now()
)]
column_names = [
'id', 'watchlist_id', 'ticker', 'entry_price', 'id', 'watchlist_id', 'ticker', 'entry_price',
'target_price', 'stop_loss', 'notes', 'created_at' 'target_price', 'stop_loss', 'notes', 'created_at'
] ]
)
column_types = [ # Verify the insert
'UInt32', 'UInt32', 'String', 'Float64', verify_result = client.query(f"""
'Float64', 'Float64', 'String', 'DateTime' SELECT * FROM stock_db.watchlist_items
] WHERE id = {next_id}
""")
# Show insert details return len(verify_result.result_rows) > 0
logger.info(f"Data to insert: {data}")
logger.info(f"Column names: {column_names}")
logger.info(f"Column types: {column_types}")
st.write("=== DATABASE INSERT ATTEMPT ===")
st.json({"data": str(data), "columns": column_names, "types": column_types})
# Perform insert
try:
client.insert(
'stock_db.watchlist_items',
data,
column_names=column_names,
column_types=column_types
)
success_msg = "Insert operation completed successfully"
logger.info(success_msg)
st.success(success_msg)
except Exception as insert_error:
error_msg = f"Insert error: {insert_error}"
logger.error(error_msg)
st.error(error_msg)
raise
# Verify the insert
verify_query = f"""
SELECT *
FROM stock_db.watchlist_items
WHERE id = {next_id}
AND watchlist_id = {watchlist_id}
AND ticker = '{item.ticker}'
"""
logger.info(f"Verification query: {verify_query}")
verify_result = client.query(verify_query)
logger.info(f"Verification result: {verify_result.result_rows}")
st.write("Verification result:", verify_result.result_rows)
if not verify_result.result_rows:
error_msg = "Verification failed - no rows found after insert"
logger.error(error_msg)
st.error(error_msg)
return False
st.success("Watchlist item added successfully!")
time.sleep(3) # Give time to see the messages
return True
except Exception as e: except Exception as e:
logger.error(f"Error adding to watchlist: {e}", exc_info=True) logger.error(f"Error adding to watchlist: {e}", exc_info=True)
return False raise
def remove_from_watchlist(item_id: int) -> bool: def remove_from_watchlist(item_id: int) -> bool:
with create_client() as client: with create_client() as client: