aaxaxax commited on
Commit
c7b50f0
·
1 Parent(s): eab558a

fix: Auto-fetch prices from yfinance if DB is empty on startup

Browse files
Files changed (1) hide show
  1. dashboard/app.py +45 -0
dashboard/app.py CHANGED
@@ -309,6 +309,50 @@ def _inject_css():
309
  def _ensure_schema():
310
  init_schema()
311
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312
  @st.cache_data(ttl=3600)
313
  def _load_forecast(symbol: str) -> dict:
314
  return predict(symbol)
@@ -1036,6 +1080,7 @@ def _render_sidebar() -> tuple[str, int]:
1036
 
1037
  def main():
1038
  _ensure_schema()
 
1039
  _inject_css()
1040
  _render_header()
1041
 
 
309
  def _ensure_schema():
310
  init_schema()
311
 
312
+ @st.cache_resource
313
+ def _ensure_prices():
314
+ """Fetch 2 years of price history from yfinance if the DB is empty.
315
+ Runs once per process — makes the app self-healing on fresh containers."""
316
+ conn = get_conn()
317
+ count = conn.execute("SELECT COUNT(*) FROM prices").fetchone()[0]
318
+ conn.close()
319
+ if count > 100:
320
+ return
321
+ try:
322
+ import yfinance as yf
323
+ from data.db import get_conn as _gc
324
+ symbols = list(SYMBOL_NAMES.keys())
325
+ ticker_data = yf.download(symbols, period="5y", auto_adjust=True, progress=False)
326
+ if ticker_data.empty:
327
+ return
328
+ conn2 = _gc()
329
+ for sym in symbols:
330
+ try:
331
+ if len(symbols) == 1:
332
+ df = ticker_data.copy()
333
+ else:
334
+ df = ticker_data.xs(sym, axis=1, level=1) if sym in ticker_data.columns.get_level_values(1) else None
335
+ if df is None or (hasattr(df, 'empty') and df.empty):
336
+ continue
337
+ df = df.reset_index()
338
+ df.columns = [c.lower() for c in df.columns]
339
+ for _, row in df.iterrows():
340
+ try:
341
+ conn2.execute(
342
+ "INSERT OR REPLACE INTO prices (date,symbol,open,high,low,close,volume,adj_close) VALUES (?,?,?,?,?,?,?,?)",
343
+ [str(row["date"])[:10], sym,
344
+ float(row.get("open", 0) or 0), float(row.get("high", 0) or 0),
345
+ float(row.get("low", 0) or 0), float(row.get("close", 0) or 0),
346
+ float(row.get("volume", 0) or 0), float(row.get("close", 0) or 0)]
347
+ )
348
+ except Exception:
349
+ pass
350
+ except Exception:
351
+ pass
352
+ conn2.close()
353
+ except Exception:
354
+ pass
355
+
356
  @st.cache_data(ttl=3600)
357
  def _load_forecast(symbol: str) -> dict:
358
  return predict(symbol)
 
1080
 
1081
  def main():
1082
  _ensure_schema()
1083
+ _ensure_prices()
1084
  _inject_css()
1085
  _render_header()
1086