"""Top Movers component — day gainers, losers, most active.""" from html import escape import streamlit as st import yfinance as yf DEFAULT_VISIBLE_MOVERS = 3 MAX_MOVERS = 8 def _toggle_mover_tab(state_key: str): st.session_state[state_key] = not st.session_state.get(state_key, False) def _inject_styles(compact: bool = False): row_template = ( "minmax(48px, 0.9fr) minmax(56px, 1fr) minmax(60px, 1fr)" if compact else "minmax(72px, 0.8fr) minmax(0, 2.6fr) minmax(90px, 1fr) minmax(110px, 1.1fr)" ) row_gap = "0.3rem" if compact else "0.85rem" name_display = "none" if compact else "block" row_padding = "0.12rem 0" if compact else "0.18rem 0" symbol_size = "0.75rem" if compact else "0.875rem" name_size = "0.75rem" if compact else "0.8125rem" price_size = "0.75rem" if compact else "0.8125rem" change_size = "0.75rem" if compact else "0.8125rem" change_meta_size = "10px" if compact else "11px" st.markdown( """ """.format( row_template=row_template, row_gap=row_gap, row_padding=row_padding, symbol_size=symbol_size, name_size=name_size, name_display=name_display, price_size=price_size, change_size=change_size, change_meta_size=change_meta_size, ), unsafe_allow_html=True, ) @st.cache_data(ttl=180) def _fetch_movers(screen: str, count: int = MAX_MOVERS) -> list[dict]: try: result = yf.screen(screen, count=count) return result.get("quotes", []) except Exception: return [] def _fmt_price(val) -> str: try: return f"${float(val):,.2f}" except Exception: return "—" def _mover_row_html(q: dict) -> str: symbol = escape(str(q.get("symbol", ""))) name = escape(str(q.get("shortName") or q.get("longName") or symbol)) price = q.get("regularMarketPrice") chg_pct = q.get("regularMarketChangePercent") chg_abs = q.get("regularMarketChange") try: chg_f = float(chg_pct) color = "#4F8C5E" if chg_f >= 0 else "#B5494B" sign = "+" if chg_f >= 0 else "" pct_str = f"{sign}{chg_f:.2f}%" except Exception: color = "#9aa0b0" pct_str = "—" try: abs_str = f"({'+' if float(chg_abs) >= 0 else ''}{float(chg_abs):.2f})" except Exception: abs_str = "" abs_str = escape(abs_str) return ( "