diff --git a/src/pages/trading/trading_system_page.py b/src/pages/trading/trading_system_page.py index 6c2ae47..18d5ea6 100644 --- a/src/pages/trading/trading_system_page.py +++ b/src/pages/trading/trading_system_page.py @@ -227,42 +227,41 @@ def trading_system_page(): # Move Add to Watch List button outside of columns if st.button("Add to Watch List", key="add_to_watchlist"): try: - # Create a container for debug output - debug_container = st.container() - 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( - ticker=ticker, - entry_price=float(entry_price), - target_price=float(target_price), - stop_loss=float(position['stop_loss']), - notes=str(notes) if notes else '' - ) - - st.write("=== WATCHLIST ITEM DETAILS ===") - st.json(vars(item)) - - success = add_to_watchlist(selected_list[0], item) - - if success: - st.success(f"Added {ticker} to watch list!") - time.sleep(3) # Give time to see success message - st.experimental_rerun() - else: - st.error("Failed to add to watch list. Check the details above.") + # Ensure tables exist + ensure_tables_exist() + + # Create watchlist item + item = WatchlistItem( + ticker=ticker, + entry_price=float(entry_price), + target_price=float(target_price), + stop_loss=float(position['stop_loss']), + notes=str(notes) if notes else '' + ) + + # Show debug information + 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 + }) + + # Add to watchlist + success = add_to_watchlist(selected_list[0], item) + + if success: + st.success(f"Added {ticker} to watchlist!") + time.sleep(2) + st.experimental_rerun() + else: + st.error("Failed to add to watchlist") except Exception as e: - st.error(f"Error adding to watchlist: {str(e)}") - logger.exception("Error in watchlist addition") + st.error(f"Error: {str(e)}") + logger.exception("Error adding to watchlist") except Exception as e: st.error(f"Error calculating position: {str(e)}") diff --git a/src/trading/watchlist.py b/src/trading/watchlist.py index c6985d6..2dc93ee 100644 --- a/src/trading/watchlist.py +++ b/src/trading/watchlist.py @@ -9,6 +9,36 @@ import time logging.basicConfig(level=logging.INFO) 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 class WatchlistItem: ticker: str @@ -39,115 +69,42 @@ def get_watchlists() -> List[dict]: def add_to_watchlist(watchlist_id: int, item: WatchlistItem) -> bool: with create_client() as client: try: - # Debug output using both logger and st.write - debug_msg = f""" - === WATCHLIST INSERT ATTEMPT === - 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 + # Get next ID + result = client.query("SELECT max(id) + 1 as next_id FROM stock_db.watchlist_items") + next_id = result.first_row[0] if result.first_row[0] is not None else 1 - # Force a container to stay visible - placeholder = st.empty() - with placeholder.container(): - # Check if watchlist exists - check_watchlist_query = f"SELECT * FROM stock_db.watchlists WHERE id = {watchlist_id}" - watchlist_result = client.query(check_watchlist_query) - logger.info(f"Watchlist check result: {watchlist_result.result_rows}") - st.write("Watchlist check result:", watchlist_result.result_rows) - - if not watchlist_result.result_rows: - error_msg = f"Watchlist ID {watchlist_id} not found" - logger.error(error_msg) - st.error(error_msg) - 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 = [ + # Insert the item + data = [( + next_id, + watchlist_id, + item.ticker, + item.entry_price, + item.target_price, + item.stop_loss, + item.notes or '', + datetime.now() + )] + + client.insert( + 'stock_db.watchlist_items', + data, + column_names=[ 'id', 'watchlist_id', 'ticker', 'entry_price', 'target_price', 'stop_loss', 'notes', 'created_at' ] - - column_types = [ - 'UInt32', 'UInt32', 'String', 'Float64', - 'Float64', 'Float64', 'String', 'DateTime' - ] - - # Show insert details - 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 + ) + + # Verify the insert + verify_result = client.query(f""" + SELECT * FROM stock_db.watchlist_items + WHERE id = {next_id} + """) + + return len(verify_result.result_rows) > 0 + except Exception as e: logger.error(f"Error adding to watchlist: {e}", exc_info=True) - return False + raise def remove_from_watchlist(item_id: int) -> bool: with create_client() as client: