diff --git a/__pycache__/stock_profile.cpython-312.pyc b/__pycache__/stock_profile.cpython-312.pyc index e6114d6..40bc964 100644 Binary files a/__pycache__/stock_profile.cpython-312.pyc and b/__pycache__/stock_profile.cpython-312.pyc differ diff --git a/__pycache__/strategy_lifecycle.cpython-312.pyc b/__pycache__/strategy_lifecycle.cpython-312.pyc index 6cc3c36..9d8d82d 100644 Binary files a/__pycache__/strategy_lifecycle.cpython-312.pyc and b/__pycache__/strategy_lifecycle.cpython-312.pyc differ diff --git a/scripts/stale_push_wlin.py b/scripts/stale_push_wlin.py index 402b8d1..bb5341c 100644 --- a/scripts/stale_push_wlin.py +++ b/scripts/stale_push_wlin.py @@ -112,8 +112,18 @@ def load_macro_line(): """加载大盘和市场的简要描述""" parts = [] try: - with open(MACRO_CTX) as f: - m = json.load(f).get("structure", {}) + # 优先 DB + import sqlite3 + db = sqlite3.connect("/home/hmo/MoFin/data/mofin.db") + row = db.execute( + "SELECT structure FROM macro_context_log " + "WHERE has_valid_data=1 ORDER BY created_at DESC LIMIT 1" + ).fetchone() + db.close() + if row and row[0]: + m = json.loads(row[0]) + else: + raise ValueError("no db data") overall = m.get("overall", "neutral") desc = m.get("description", "") if "bearish" in overall: @@ -123,7 +133,19 @@ def load_macro_line(): elif desc: parts.append(f"大盘{desc}") except Exception: - pass + try: + with open(MACRO_CTX) as f: + m = json.load(f).get("structure", {}) + overall = m.get("overall", "neutral") + desc = m.get("description", "") + if "bearish" in overall: + parts.append("大盘偏弱") + elif overall == "bullish": + parts.append("大盘偏强") + elif desc: + parts.append(f"大盘{desc}") + except Exception: + pass try: with open(MARKET_JSON) as f: mk = json.load(f) diff --git a/scripts/xiaoguo_signal_consumer.py b/scripts/xiaoguo_signal_consumer.py index d8e35f1..50c1cd5 100644 --- a/scripts/xiaoguo_signal_consumer.py +++ b/scripts/xiaoguo_signal_consumer.py @@ -74,19 +74,41 @@ def quick_assess(quote): score = 0 reasons = [] - # 大盘环境(简化:交易日9:30-15:00且在涨) - # 引用 macro_context.json 中的大盘方向 + # 大盘环境,从DB读(回退JSON) try: - mc = json.loads((DATA / "macro_context.json").read_text()) - sh = mc.get("shanghai", {}).get("change_pct", 0) + import sqlite3 + conn = sqlite3.connect(str(DB_PATH)) + row = conn.execute( + "SELECT indices FROM macro_context_log WHERE has_valid_data=1 ORDER BY created_at DESC LIMIT 1" + ).fetchone() + conn.close() + if row and row[0]: + mc = json.loads(row[0]) + else: + raise ValueError + sh = 0 + for k, v in mc.items(): + if "上证" in k: + sh = v.get("change_pct", 0) + break if sh > 0.5: score += 1 reasons.append(f"大盘+{sh:.1f}%偏强") elif sh < -0.5: score -= 1 reasons.append(f"大盘{sh:.1f}%偏弱") - except: - pass + except Exception: + try: + mc = json.loads((DATA / "macro_context.json").read_text()) + sh = mc.get("shanghai", {}).get("change_pct", 0) + if sh > 0.5: + score += 1 + reasons.append(f"大盘+{sh:.1f}%偏强") + elif sh < -0.5: + score -= 1 + reasons.append(f"大盘{sh:.1f}%偏弱") + except: + pass # 技术面:涨跌幅 chg = quote.get("change_pct", 0) diff --git a/stock_profile.py b/stock_profile.py index c02fdc5..1fb7c04 100644 --- a/stock_profile.py +++ b/stock_profile.py @@ -119,7 +119,21 @@ def load_mtf_cache() -> dict: def load_macro() -> dict: - """加载宏观上下文""" + """加载宏观上下文,优先DB""" + try: + import sqlite3 + conn = sqlite3.connect(os.path.join(DATA_DIR, "mofin.db")) + row = conn.execute( + "SELECT indices, structure, key_sectors FROM macro_context_log " + "WHERE has_valid_data=1 ORDER BY created_at DESC LIMIT 1" + ).fetchone() + conn.close() + if row: + return {"indices": json.loads(row[0] or "{}"), + "structure": json.loads(row[1] or "{}"), + "key_sectors": json.loads(row[2] or "[]")} + except: + pass try: with open(MACRO_PATH) as f: return json.load(f) diff --git a/strategy_lifecycle.py b/strategy_lifecycle.py index 4a0f6bf..616b748 100644 --- a/strategy_lifecycle.py +++ b/strategy_lifecycle.py @@ -286,22 +286,39 @@ def compute_sector_adjustment(code, market_ctx, stock_sector_map): def load_macro_context(): - """读取宏观上下文,返回 (bias, desc),bias 取 0.8/1.0/1.1 分别对应 bearish/neutral/bullish""" + """读取宏观上下文,返回 (bias, desc),优先 DB,回退 JSON""" try: - with open(MACRO_CONTEXT_PATH) as f: - ctx = json.load(f) - overall = ctx.get("structure", {}).get("overall", "neutral") - desc = ctx.get("structure", {}).get("description", "") - if "bearish" in overall: - return 0.8, f"宏观{desc}" - elif overall == "bullish": - return 1.05, f"宏观{desc}" - elif overall == "strong_bullish": - return 1.1, f"宏观{desc}" + import sqlite3 + from pathlib import Path + conn = sqlite3.connect(str(Path(__file__).parent.parent / "data" / "mofin.db")) + row = conn.execute( + "SELECT indices, structure FROM macro_context_log " + "WHERE has_valid_data=1 ORDER BY created_at DESC LIMIT 1" + ).fetchone() + conn.close() + if row: + indices = json.loads(row[0]) if row[0] else {} + structure = json.loads(row[1]) if row[1] else {} + overall = structure.get("overall", "neutral") + desc = structure.get("description", "") else: - return 1.0, f"宏观{desc}" + raise ValueError("no db data") except Exception: - return 1.0, "宏观未加载" + try: + with open(MACRO_CONTEXT_PATH) as f: + ctx = json.load(f) + overall = ctx.get("structure", {}).get("overall", "neutral") + desc = ctx.get("structure", {}).get("description", "") + except Exception: + return 1.0, "宏观未加载" + if "bearish" in overall: + return 0.8, f"宏观{desc}" + elif overall == "bullish": + return 1.05, f"宏观{desc}" + elif overall == "strong_bullish": + return 1.1, f"宏观{desc}" + else: + return 1.0, f"宏观{desc}" def batch_fetch_prices(codes): diff --git a/strategy_tree.py b/strategy_tree.py index c85f43c..985cea0 100644 --- a/strategy_tree.py +++ b/strategy_tree.py @@ -70,15 +70,30 @@ def detect_scenario(): confidence = 0.5 try: - macro = json.load(open(MACRO_PATH)) - market = json.load(open(MARKET_PATH)) + # 优先 DB + import sqlite3 + from pathlib import Path + db = sqlite3.connect(str(Path(__file__).parent / "data" / "mofin.db")) + mrow = db.execute( + "SELECT indices, structure, sector_mood FROM macro_context_log " + "WHERE has_valid_data=1 ORDER BY created_at DESC LIMIT 1" + ).fetchone() + db.close() + if mrow: + structure = json.loads(mrow[1]) if mrow[1] else {} + overall = structure.get("overall", "").lower() + mood = (mrow[2] or "").lower() if len(mrow) > 2 else "" + else: + raise ValueError("no db data") except Exception: - return {"id": scenario_id, "label": "默认-弱势震荡", "confidence": 0.3, "portfolio_action": "观望"} - - mood = market.get("mood", "").lower() - # Try to get trend from macro_context - structure = macro.get("structure", {}) - overall = structure.get("overall", "").lower() + try: + macro = json.load(open(MACRO_PATH)) + market = json.load(open(MARKET_PATH)) + mood = market.get("mood", "").lower() + structure = macro.get("structure", {}) + overall = structure.get("overall", "").lower() + except Exception: + return {"id": "weak_consolidation", "label": "默认-弱势震荡", "confidence": 0.3, "portfolio_action": "观望"} trend_desc = structure.get("description", "").lower() # Check for sharp decline diff --git a/system_audit.py b/system_audit.py index 14cb0fc..8d1b004 100644 --- a/system_audit.py +++ b/system_audit.py @@ -128,16 +128,19 @@ def audit_portfolio(conn): # ── 6. 数据管道审计 ── def audit_pipeline(): - # 检查market.json是否今天更新 + # 检查DB市场数据是否今天更新 try: - mkt = json.loads((DATA_DIR / "market.json").read_text()) - mkt_ts = mkt.get("timestamp", "") - if mkt_ts[:10] == datetime.now().strftime("%Y-%m-%d"): - log_ok("数据管道", f"市场数据今天更新({mkt_ts})") + conn = sqlite3.connect(str(DATA_DIR / "mofin.db")) + row = conn.execute( + "SELECT created_at FROM market_snapshots ORDER BY created_at DESC LIMIT 1" + ).fetchone() + conn.close() + if row and row[0][:10] == datetime.now().strftime("%Y-%m-%d"): + log_ok("数据管道", f"市场数据今天更新({row[0]})") else: - log_issue("数据管道", "HIGH", f"市场数据未更新, 最后{mkt_ts}") - except: - log_issue("数据管道", "HIGH", "market.json缺失") + log_issue("数据管道", "HIGH", f"市场数据未更新(DB), 最后{row[0] if row else '无数据'}") + except Exception as e: + log_issue("数据管道", "HIGH", f"DB检查失败: {e}") # ── 7. 系统服务 ──