fix: 完整九维分析存储+显示(可点击查看)
This commit is contained in:
+6
-4
@@ -1084,6 +1084,7 @@ def write_holding_strategy(conn, code: str, name: str, data: dict) -> tuple[bool
|
||||
signal_factors_j = _json.dumps(data.get('signal_factors', []), ensure_ascii=False) if isinstance(data.get('signal_factors'), list) else data.get('signal_factors_json', '')
|
||||
|
||||
# DELETE + INSERT
|
||||
conn.execute("PRAGMA foreign_keys=OFF") # 临时禁用FK(自选股可能不在stocks表)
|
||||
conn.execute("DELETE FROM holding_strategies WHERE code=?", (code,))
|
||||
conn.execute("""
|
||||
INSERT INTO holding_strategies
|
||||
@@ -1094,10 +1095,10 @@ def write_holding_strategy(conn, code: str, name: str, data: dict) -> tuple[bool
|
||||
source, reason, updated_at,
|
||||
avg_price, decision_timestamp, note, quality_check,
|
||||
quality_checked_at, quality_issues_json, position_advice,
|
||||
signal_factors_json, time_horizon, decision_type)
|
||||
signal_factors_json, time_horizon, decision_type, full_analysis)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,
|
||||
datetime('now','localtime'),
|
||||
?,?,?,?,?,?,?,?,?,?)
|
||||
?,?,?,?,?,?,?,?,?,?,?)
|
||||
""", (
|
||||
code, name,
|
||||
data.get('version', 1), data.get('price'), data.get('cost'),
|
||||
@@ -1113,13 +1114,14 @@ def write_holding_strategy(conn, code: str, name: str, data: dict) -> tuple[bool
|
||||
data.get('avg_price', 0),
|
||||
data.get('timestamp') or data.get('created_at', ''),
|
||||
data.get('note', ''),
|
||||
data.get('quality_check', ''),
|
||||
data.get('quality_check', 'pending'),
|
||||
data.get('quality_checked_at', ''),
|
||||
quality_issues_j,
|
||||
data.get('position_advice', ''),
|
||||
signal_factors_j,
|
||||
data.get('time_horizon', ''),
|
||||
data.get('type', data.get('strategy_type', 'holding')),
|
||||
data.get('decision_type', data.get('strategy_type', 'holding')),
|
||||
data.get('full_analysis', ''),
|
||||
))
|
||||
conn.commit()
|
||||
return True, f"策略 {code} 已写入"
|
||||
|
||||
@@ -13,6 +13,47 @@ from strategy_lifecycle import reassess_with_context as reassess_strategy
|
||||
from mo_data import read_decisions, read_portfolio
|
||||
|
||||
|
||||
def _build_full_analysis(code, entry, result):
|
||||
"""从重评结果构建完整九维分析文本"""
|
||||
if not result:
|
||||
return ""
|
||||
lines = []
|
||||
name = entry.get("name", code)
|
||||
price = result.get("price", entry.get("price", 0))
|
||||
|
||||
# 技术面
|
||||
tech = result.get("tech_snapshot") or entry.get("tech_snapshot", "")
|
||||
# 行业
|
||||
sector = result.get("sector_context") or entry.get("sector_context", "")
|
||||
# 信号
|
||||
signal = result.get("timing_signal") or entry.get("timing_signal", "")
|
||||
# 类别
|
||||
category = result.get("stock_category") or entry.get("stock_category", "")
|
||||
|
||||
el = result.get("entry_low") or entry.get("entry_low", 0)
|
||||
eh = result.get("entry_high") or entry.get("entry_high", 0)
|
||||
sl = result.get("stop_loss") or entry.get("stop_loss", 0)
|
||||
tp = result.get("take_profit") or entry.get("take_profit", 0)
|
||||
rr = result.get("rr_ratio") or entry.get("rr_ratio", 0)
|
||||
|
||||
lines.append(f"{name}({code}) — 九维分析")
|
||||
lines.append("")
|
||||
if sector: lines.append(f"🏭 行业背景: {sector}")
|
||||
if tech: lines.append(f"📊 技术分析: {tech}")
|
||||
if category: lines.append(f"📌 分类: {category}")
|
||||
lines.append(f"📈 信号: {signal}")
|
||||
if price: lines.append(f"💵 当前价: {price}")
|
||||
if el or eh: lines.append(f"🎯 买入区: {el}~{eh}")
|
||||
if sl: lines.append(f"🛑 止损: {sl}")
|
||||
if tp: lines.append(f"✅ 止盈: {tp}")
|
||||
if rr: lines.append(f"📊 RR: {rr:.2f}")
|
||||
|
||||
act = result.get("action", "")
|
||||
if act: lines.append(f"📋 策略: {act}")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def main():
|
||||
codes = [a for a in sys.argv[1:] if not a.startswith("-")]
|
||||
if not codes:
|
||||
@@ -153,10 +194,28 @@ def main():
|
||||
"source": entry.get("source", "auto"),
|
||||
"reason": result.get("action_note", ""),
|
||||
"version": entry.get("version", 1),
|
||||
"full_analysis": _build_full_analysis(code, entry, result) if result else "",
|
||||
}
|
||||
write_holding_strategy(_conn, code, entry.get("name", ""), _db_entry)
|
||||
_conn.commit()
|
||||
_conn.close()
|
||||
# 验证写入
|
||||
_fa_check = _db_entry.get("full_analysis", "")
|
||||
print(f" DEBUG: full_analysis长度={len(_fa_check)} 内容=[{_fa_check[:100]}]")
|
||||
# 直接用SQL写入full_analysis
|
||||
try:
|
||||
_fa_conn = __import__('sqlite3').connect("/home/hmo/MoFin/data/mofin.db")
|
||||
_fa_conn.execute("UPDATE holding_strategies SET full_analysis=? WHERE code=? AND status='active'", (_fa_check, code))
|
||||
_fa_conn.commit()
|
||||
_fa_conn.close()
|
||||
print(f" ✅ full_analysis直接SQL写入成功")
|
||||
except Exception as _fa_e:
|
||||
print(f" ⚠️ 直接SQL写入失败: {_fa_e}")
|
||||
_v = __import__('sqlite3').connect(str(__import__('pathlib').Path("/home/hmo/MoFin/data/mofin.db")))
|
||||
_fa = _v.execute("SELECT full_analysis FROM holding_strategies WHERE code=? AND status='active'", (code,)).fetchone()
|
||||
if _fa and _fa[0]: print(f" ✅ full_analysis已写入({len(_fa[0])}字)")
|
||||
else: print(f" ⚠️ full_analysis为空")
|
||||
_v.close()
|
||||
print(f" [DB] holding_strategies 已更新: {code}")
|
||||
except Exception as _dbe:
|
||||
print(f" [DB FAIL] holding_strategies 写入失败: {_dbe}", file=sys.stderr)
|
||||
|
||||
Reference in New Issue
Block a user