feat: Simplify watchlist functionality and add table creation checks
This commit is contained in:
parent
a6d7a3fb54
commit
579f870c08
@ -227,19 +227,10 @@ 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]
|
|
||||||
})
|
|
||||||
|
|
||||||
|
# Create watchlist item
|
||||||
item = WatchlistItem(
|
item = WatchlistItem(
|
||||||
ticker=ticker,
|
ticker=ticker,
|
||||||
entry_price=float(entry_price),
|
entry_price=float(entry_price),
|
||||||
@ -248,21 +239,29 @@ def trading_system_page():
|
|||||||
notes=str(notes) if notes else ''
|
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
|
||||||
|
})
|
||||||
|
|
||||||
|
# Add to watchlist
|
||||||
success = add_to_watchlist(selected_list[0], item)
|
success = add_to_watchlist(selected_list[0], item)
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
st.success(f"Added {ticker} to watchlist!")
|
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)}")
|
||||||
|
|||||||
@ -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
|
|
||||||
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
|
|
||||||
|
|
||||||
# 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
|
# Get next ID
|
||||||
id_query = "SELECT max(id) + 1 as next_id FROM stock_db.watchlist_items"
|
result = client.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
|
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
|
# Insert the item
|
||||||
data = [(
|
data = [(
|
||||||
int(next_id),
|
next_id,
|
||||||
int(watchlist_id),
|
watchlist_id,
|
||||||
str(item.ticker),
|
item.ticker,
|
||||||
float(item.entry_price),
|
item.entry_price,
|
||||||
float(item.target_price),
|
item.target_price,
|
||||||
float(item.stop_loss),
|
item.stop_loss,
|
||||||
str(item.notes or ''),
|
item.notes or '',
|
||||||
datetime.now()
|
datetime.now()
|
||||||
)]
|
)]
|
||||||
|
|
||||||
|
client.insert(
|
||||||
|
'stock_db.watchlist_items',
|
||||||
|
data,
|
||||||
column_names=[
|
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 = [
|
|
||||||
'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 the insert
|
||||||
verify_query = f"""
|
verify_result = client.query(f"""
|
||||||
SELECT *
|
SELECT * FROM stock_db.watchlist_items
|
||||||
FROM stock_db.watchlist_items
|
|
||||||
WHERE id = {next_id}
|
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:
|
return len(verify_result.result_rows) > 0
|
||||||
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:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user