From 9bc0cca1743d0b4b60cc1642e4823d479ecfcfec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=A5=E5=BE=AE?= Date: Fri, 3 Jul 2026 23:15:18 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20HK=20currency=E2=86=92CNY=20+=20portfoli?= =?UTF-8?q?o=5Fsummary=20+=20LLM=20prompt=20evaluation.json=E2=86=92DB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- prompt_manager/init_registry.py | 2 +- scripts/close_audit.py | 87 +++++++++++++++++++++++++++++ scripts/fix_currency_and_summary.py | 42 ++++++++++++++ scripts/fix_decisions_currency.py | 6 ++ 4 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 scripts/close_audit.py create mode 100644 scripts/fix_currency_and_summary.py create mode 100644 scripts/fix_decisions_currency.py diff --git a/prompt_manager/init_registry.py b/prompt_manager/init_registry.py index 31a74dc..74bf29b 100644 --- a/prompt_manager/init_registry.py +++ b/prompt_manager/init_registry.py @@ -248,7 +248,7 @@ add_version("evaluation-daily", PromptVersion( changelog="新增反馈闭环机制:识别6种策略信号(买入区从未触发/频繁止损/价格远超止盈/理论实际差距/连续正确/连续错误),自动生成调整建议", content="""策略评估 v2(当前): 1. 运行 strategy_evaluator.py -2. 读 evaluation.json + accuracy_stats.json +2. 从 DB strategy_evaluations + accuracy_stats 表读取 3. 识别6种信号并生成调整建议 4. 固化经验到 knowledge-log 5. 无变化输出 SILENT 抑制推送 diff --git a/scripts/close_audit.py b/scripts/close_audit.py new file mode 100644 index 0000000..1d757e5 --- /dev/null +++ b/scripts/close_audit.py @@ -0,0 +1,87 @@ +"""收盘后全面数据审计""" +import sys, sqlite3 +sys.path.insert(0, '/home/hmo/MoFin') +from mo_models import is_hk_stock, get_hk_rate, calc_total_assets, calc_total_mv, calc_position_pct +from mo_data import read_portfolio, read_decisions, read_watchlist + +pf = read_portfolio() +dec = read_decisions() +wl = read_watchlist() +rate = get_hk_rate() + +print(f"HK_RATE: {rate}") +print() + +# ── 1. 持仓数据审计 ── +print("=== 持仓 Holdings ===") +errors = [] +hk_cny_issues = [] +total_mv = 0 +total_cost = 0 + +for h in pf.get('holdings', []): + code = str(h.get('code', '')) + name = h.get('name', '?') + cost = h.get('cost') or 0 + price = h.get('price') or 0 + shares = h.get('shares') or 0 + curr = h.get('currency', h.get('_currency', '?')) + mv = price * shares + total_mv += mv + total_cost += cost * shares + + is_hk = is_hk_stock(code) + flag = 'HK' if is_hk else 'A ' + + # 检查币种 + if is_hk and curr != 'CNY': + hk_cny_issues.append(f"{code} {name}: currency={curr} (应为CNY)") + + # 检查 cost=0 的股票 + if cost <= 0 and shares > 0: + errors.append(f"{code} {name}: cost=0 但持仓{shares}股") + + pnl_pct = (price - cost) / cost * 100 if cost > 0 else 0 + print(f" [{flag}] {code} {name}: cost={cost:.2f} price={price:.2f} shares={shares} mv={mv:.0f} pnl={pnl_pct:+.1f}% curr={curr}") + +total_pnl = total_mv - total_cost +print(f"\n total_mv={total_mv:.2f} total_cost={total_cost:.2f} total_pnl={total_pnl:.2f}") + +# ── 2. 汇总数据审计 ── +print("\n=== Portfolio Summary ===") +print(f" stored total_assets: {pf.get('total_assets')}") +print(f" stored total_mv: {pf.get('total_mv')}") +print(f" stored cash: {pf.get('cash')}") +print(f" stored frozen_cash: {pf.get('frozen_cash')}") +print(f" stored total_pnl: {pf.get('total_pnl')}") + +calc_ta = total_mv + (pf.get('cash') or 0) + (pf.get('frozen_cash') or 0) +print(f" calculated total_assets: {calc_ta:.2f}") + +if abs((pf.get('total_assets') or 0) - calc_ta) > 1: + errors.append(f"total_assets mismatch: stored={pf.get('total_assets')} vs calc={calc_ta:.2f}") + +# ── 3. 决策数据审计 ── +print("\n=== Decisions ===") +cnys = 0 +hkds = 0 +none_curr = 0 +for d in dec.get('decisions', []): + c = d.get('currency', '') + if c == 'CNY': cnys += 1 + elif c == 'HKD': hkds += 1 + else: none_curr += 1 +print(f" CNY: {cnys} HKD: {hkds} None: {none_curr}") +if hkds > 0: + errors.append(f"Decisions: {hkds} entries still have currency=HKD") + +# ── 4. 错误汇总 ── +print(f"\n{'='*40}") +if hk_cny_issues: + print("HK币种问题:") + for i in hk_cny_issues: print(f" ❌ {i}") +if errors: + print("其他问题:") + for e in errors: print(f" ❌ {e}") +if not hk_cny_issues and not errors: + print("✅ 数据审计全部通过") diff --git a/scripts/fix_currency_and_summary.py b/scripts/fix_currency_and_summary.py new file mode 100644 index 0000000..e2016ff --- /dev/null +++ b/scripts/fix_currency_and_summary.py @@ -0,0 +1,42 @@ +"""Fix: HK stock currency=CYN, recalc portfolio_summary""" +import sqlite3, sys +sys.path.insert(0, '/home/hmo/MoFin') +from mo_models import is_hk_stock +from datetime import datetime + +db = sqlite3.connect('/home/hmo/web-dashboard/data/mofin.db') + +# 1. Fix all HK stock currency to CNY +fixed = 0 +for r in db.execute("SELECT code, name, cost, price, shares, currency FROM holdings WHERE is_active=1"): + code, name, cost, price, shares, curr = r + if is_hk_stock(str(code)): + db.execute("UPDATE holdings SET currency='CNY' WHERE code=?", (code,)) + print(f" FIXED HK currency: {code} {name}: {curr} -> CNY") + fixed += 1 +print(f"Fixed {fixed} HK stock currencies\n") + +# 2. Recalc portfolio_summary +rows = db.execute("SELECT code, shares, cost, price FROM holdings WHERE is_active=1").fetchall() +total_mv = sum((r[3] or 0) * (r[1] or 0) for r in rows) +total_cost = sum((r[2] or 0) * (r[1] or 0) for r in rows) +total_pnl = total_mv - total_cost + +sr = db.execute("SELECT cash, frozen_cash FROM portfolio_summary WHERE id=1").fetchone() +cash = sr[0] or 0 +frozen = sr[1] or 0 +total_assets = total_mv + cash + frozen +position_pct = round(total_mv / total_assets * 100, 2) if total_assets > 0 else 0 + +db.execute("UPDATE portfolio_summary SET total_mv=?, total_assets=?, total_pnl=?, position_pct=?, updated_at=? WHERE id=1", + (round(total_mv,2), round(total_assets,2), round(total_pnl,2), position_pct, datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) +print(f"portfolio_summary: mv={total_mv:.2f} ta={total_assets:.2f} pnl={total_pnl:.2f} pos={position_pct}%") + +# 3. Check 00700 cost +r = db.execute("SELECT cost FROM holdings WHERE code='00700'").fetchone() +if r and (r[0] is None or r[0] == 0): + print("\n⚠️ 00700 腾讯 cost=0 — 需要从 holding.xls 重新导入") + +db.commit() +db.close() +print("\nDone.") diff --git a/scripts/fix_decisions_currency.py b/scripts/fix_decisions_currency.py new file mode 100644 index 0000000..ce8062d --- /dev/null +++ b/scripts/fix_decisions_currency.py @@ -0,0 +1,6 @@ +import sqlite3 +db = sqlite3.connect('/home/hmo/web-dashboard/data/mofin.db') +n = db.execute("UPDATE holding_strategies SET currency='CNY' WHERE currency='HKD'").rowcount +db.commit() +print(f"Fixed {n} decision currencies") +db.close()