""" Cycle Actions — standalone "refresh-price-data" action. Downloads fresh OHLCV for every watchlist instrument and caches it in price_data_cache. Deliberately independent from the technical-indicators / wavelet code paths (which each do their own live yfinance fetch) — this is an inspection/refresh tool for decomposing a cycle, not a shared cache other steps depend on, so it can't regress the already-tested live cycle path. """ import logging from typing import Any, Dict logger = logging.getLogger(__name__) def refresh_watchlist_price_data(period: str = "3mo") -> Dict[str, Any]: from services.database import get_instruments_watchlist, upsert_price_data from services.data_fetcher import get_historical tickers = [w["ticker"] for w in get_instruments_watchlist()] per_ticker: Dict[str, int] = {} failed = [] for ticker in tickers: try: rows = get_historical(ticker, period=period, interval="1d") if not rows: failed.append(ticker) continue n = upsert_price_data(ticker, rows) per_ticker[ticker] = n except Exception as e: logger.warning(f"[PriceCache] Failed to refresh {ticker}: {e}") failed.append(ticker) return { "tickers_refreshed": len(per_ticker), "rows_written": sum(per_ticker.values()), "per_ticker": per_ticker, "failed": failed, }