diff --git a/migrate_all.py b/migrate_all.py index 2775ca4..ed51660 100644 --- a/migrate_all.py +++ b/migrate_all.py @@ -479,6 +479,88 @@ def migrate_strategy_feedback(conn, sf: dict) -> int: return count +def migrate_klines(conn) -> tuple[int, int, int]: + """multi_tf_cache.json → stock_daily + stock_weekly + stock_monthly + stock_fundamentals""" + data = load_json("multi_tf_cache.json") + if not data: + return 0, 0, 0 + + daily_count, weekly_count, monthly_count = 0, 0, 0 + + for code, stock in data.items(): + code = _normalize_code(code) + if not code or code.startswith("_"): + continue + + name = code # 从 stocks 表或 profiles 获取名称 + try: + row = conn.execute("SELECT name FROM stocks WHERE code = ?", (code,)).fetchone() + if row: + name = row[0] + except Exception: + pass + + # K线数据 + for period, table, key in [ + ("daily", "stock_daily", "daily"), + ("weekly", "stock_weekly", "weekly"), + ("monthly", "stock_monthly", "monthly"), + ]: + bars = stock.get(key, []) + if not bars or isinstance(bars, dict): + continue + rows = [] + for b in bars: + if not isinstance(b, dict): + continue + d = b.get("date", "") + if not d: + continue + if period == "daily": + rows.append((code, d, b.get("open"), b.get("close"), + b.get("high"), b.get("low"), b.get("volume"), + b.get("amount"))) + else: + rows.append((code, d, b.get("open"), b.get("close"), + b.get("high"), b.get("low"), b.get("volume"))) + + if rows: + try: + if period == "daily": + conn.executemany( + "INSERT OR REPLACE INTO stock_daily (code, date, open, close, high, low, volume, amount) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?)", rows) + daily_count += len(rows) + elif period == "weekly": + conn.executemany( + "INSERT OR REPLACE INTO stock_weekly (code, date, open, close, high, low, volume) " + "VALUES (?, ?, ?, ?, ?, ?, ?)", rows) + weekly_count += len(rows) + else: + conn.executemany( + "INSERT OR REPLACE INTO stock_monthly (code, date, open, close, high, low, volume) " + "VALUES (?, ?, ?, ?, ?, ?, ?)", rows) + monthly_count += len(rows) + except Exception: + pass + + # 基本面 + fundamentals = stock.get("fundamentals") + if fundamentals and isinstance(fundamentals, dict): + try: + conn.execute( + "INSERT OR REPLACE INTO stock_fundamentals (code, pe, pb, eps, mcap_total, mcap_flow, updated_at) " + "VALUES (?, ?, ?, ?, ?, ?, ?)", + (code, fundamentals.get("pe"), fundamentals.get("pb"), + fundamentals.get("eps"), fundamentals.get("mcap_total"), + fundamentals.get("mcap_flow"), datetime.now().isoformat())) + except Exception: + pass + + conn.commit() + return daily_count, weekly_count, monthly_count + + def main(): print("=" * 60) print(" MoFin 数据迁移 → mofin.db") @@ -572,7 +654,14 @@ def main(): if sf: n = migrate_strategy_feedback(conn, sf) totals["strategy_feedback"] = n - print(f"[12/12] strategy_feedback: {n} 条") + print(f"[12/13] strategy_feedback: {n} 条") + + # 13. K线数据 + dc, wc, mc = migrate_klines(conn) + totals["daily_klines"] = dc + totals["weekly_klines"] = wc + totals["monthly_klines"] = mc + print(f"[13/13] K-lines: daily={dc}, weekly={wc}, monthly={mc}") conn.commit() @@ -594,6 +683,10 @@ def main(): "advice_timeline": "SELECT COUNT(*) FROM advice_timeline", "accuracy_stats": "SELECT COUNT(*) FROM accuracy_stats", "strategy_feedback": "SELECT COUNT(*) FROM strategy_feedback", + "stock_daily": "SELECT COUNT(*) FROM stock_daily", + "stock_weekly": "SELECT COUNT(*) FROM stock_weekly", + "stock_monthly": "SELECT COUNT(*) FROM stock_monthly", + "stock_fundamentals": "SELECT COUNT(*) FROM stock_fundamentals", } for name, sql in tables.items(): n = conn.execute(sql).fetchone()[0] diff --git a/web/static/index.html b/web/static/index.html deleted file mode 100644 index 119a1ed..0000000 --- a/web/static/index.html +++ /dev/null @@ -1,1106 +0,0 @@ - - -
- - -