refactor: 消费者切 SQLite 优先读取
切换策略: SQLite 优先 → 失败回退 JSON price_events (100%覆盖): - strategy_feedback.py: run() 优先 query_price_events() - system_health_check.py: 优先 query_price_events() + query_price_events_by_date() stock_sector_map (100%覆盖): - strategy_lifecycle.py: load_stock_sector_map() 优先 stock_sectors 表 market.json (85%覆盖): - strategy_lifecycle.py: load_market_context() 优先 query_latest_market() - market_insight.py: generate() 优先 query_latest_market() portfolio.json + watchlist.json (70%覆盖): - strategy_lifecycle.py: regenerate_all() 优先 query_holdings() + query_watchlist() - server.py: /api/portfolio, /api/watchlist, /api/overview, /api/market 优先 SQLite 所有改动保留 JSON 回退路径,SQLite 不可用时自动降级
This commit is contained in:
+58
-13
@@ -77,11 +77,24 @@ def load_stock_sector_map():
|
||||
stock_sector_map.json 格式: {code: [sector1, sector2, ...]}
|
||||
跳过 _note, _created_at 等元数据键。
|
||||
"""
|
||||
# 优先从 SQLite 读取
|
||||
try:
|
||||
from mofin_db import get_conn, query_sector_stocks
|
||||
conn = get_conn()
|
||||
# 从 stock_sectors 表反向构建 code→[sectors] 映射
|
||||
rows = conn.execute("SELECT code, sector_name FROM stock_sectors ORDER BY code").fetchall()
|
||||
conn.close()
|
||||
code_to_sectors = {}
|
||||
for code, sector in rows:
|
||||
if code not in code_to_sectors:
|
||||
code_to_sectors[code] = []
|
||||
code_to_sectors[code].append(sector)
|
||||
return code_to_sectors
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
with open(STOCK_SECTOR_MAP_PATH) as f:
|
||||
data = json.load(f)
|
||||
# stock_sector_map.json 直接是 code→[sectors] 格式
|
||||
# 过滤掉 _note, _created_at 等元数据键
|
||||
code_to_sectors = {}
|
||||
for key, value in data.items():
|
||||
if key.startswith("_"):
|
||||
@@ -94,13 +107,37 @@ def load_stock_sector_map():
|
||||
|
||||
|
||||
def load_market_context():
|
||||
"""读取市场上下文(market.json),返回 (sector_perf, breadth, sentiment, mood)
|
||||
|
||||
sector_perf: {sector_name: sector_data_dict} — 所有行业板块数据
|
||||
breadth: up_ratio 值(如27.8)
|
||||
sentiment: market.json 的 mood(bearish/neutral/bullish)
|
||||
top_gainers/losers: 涨幅/跌幅前5
|
||||
"""
|
||||
"""读取市场上下文,优先 SQLite,回退 market.json"""
|
||||
# 优先从 SQLite 读取
|
||||
try:
|
||||
from mofin_db import get_conn, query_latest_market
|
||||
conn = get_conn()
|
||||
market = query_latest_market(conn)
|
||||
conn.close()
|
||||
if market and market.get("sectors"):
|
||||
sector_perf = {}
|
||||
for s in market["sectors"]:
|
||||
name = s.get("name", "")
|
||||
if name:
|
||||
sector_perf[name] = {
|
||||
"change": s.get("change_pct", 0),
|
||||
"up_count": s.get("up_count", 0),
|
||||
"down_count": s.get("down_count", 0),
|
||||
"net_inflow": s.get("net_inflow", 0),
|
||||
"lead_stock": s.get("lead_stock", ""),
|
||||
"lead_stock_change": s.get("lead_stock_change", 0),
|
||||
}
|
||||
return {
|
||||
"sector_perf": sector_perf,
|
||||
"breadth": market.get("up_ratio", 50),
|
||||
"mood": market.get("mood", "neutral"),
|
||||
"top_gainers": {g["name"]: g["change_pct"] for g in market.get("top_gainers", [])},
|
||||
"top_losers": {g["name"]: g["change_pct"] for g in market.get("top_losers", [])},
|
||||
"total_sectors": len(market["sectors"]),
|
||||
"market_timestamp": market.get("timestamp", ""),
|
||||
}
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
with open(MARKET_CONTEXT_PATH) as f:
|
||||
market = json.load(f)
|
||||
@@ -117,7 +154,6 @@ def load_market_context():
|
||||
"lead_stock": s.get("lead_stock", ""),
|
||||
"lead_stock_change": s.get("lead_stock_change", 0),
|
||||
}
|
||||
# 涨幅/跌幅前5
|
||||
top_gainers = {s.get("name", ""): s.get("change", 0)
|
||||
for s in market.get("top_gainers", [])}
|
||||
top_losers = {s.get("name", ""): s.get("change", 0)
|
||||
@@ -896,9 +932,18 @@ def check_sector_alerts(market_ctx, stock_sector_map, holdings, wl):
|
||||
|
||||
def regenerate_all(stdout=True):
|
||||
"""全量重评所有持仓+自选策略"""
|
||||
pf = safe_json_load(PORTFOLIO_PATH, {})
|
||||
wl_path = WATCHLIST_PATH
|
||||
wl = safe_json_load(wl_path, {})
|
||||
# 优先从 SQLite 读取
|
||||
try:
|
||||
from mofin_db import get_conn, query_holdings, query_watchlist
|
||||
conn = get_conn()
|
||||
holdings = query_holdings(conn)
|
||||
wl_stocks = query_watchlist(conn)
|
||||
conn.close()
|
||||
pf = {"holdings": holdings}
|
||||
wl = {"stocks": wl_stocks}
|
||||
except Exception:
|
||||
pf = safe_json_load(PORTFOLIO_PATH, {})
|
||||
wl = safe_json_load(WATCHLIST_PATH, {})
|
||||
|
||||
all_stocks = {}
|
||||
for item in pf.get("holdings", []):
|
||||
|
||||
Reference in New Issue
Block a user