#!/usr/bin/env python3 """每30分钟扫描所有持仓的分支状态,发现可操作的分支就推""" import sys, json, os sys.path.insert(0, '/home/hmo/MoFin') sys.path.insert(0, '/home/hmo/web-dashboard') from strategy_tree import detect_scenario DEC_PATH = '/home/hmo/web-dashboard/data/decisions.json' PF_PATH = '/home/hmo/web-dashboard/data/portfolio.json' XMPP_BRIDGE = "http://127.0.0.1:5805/" XMPP_USER = "hmo@yoin.fun" def push(msg): try: from urllib.request import Request, urlopen payload = json.dumps({"to": XMPP_USER, "body": msg, "type": "chat"}).encode() req = Request(XMPP_BRIDGE, data=payload, headers={"Content-Type": "application/json"}) urlopen(req, timeout=5) except Exception: pass def main(): scenario = detect_scenario() if not scenario.get('id'): return 0 # SILENT alives = [] dec = json.load(open(DEC_PATH)) pf = json.load(open(PF_PATH)) pf_codes = {h['code'] for h in pf.get('holdings', [])} for e in dec.get('decisions', []): code = e.get('code', '') tree = e.get('strategy_tree', {}) if not tree or not tree.get('branches'): continue branches = tree['branches'] price = e.get('price', 0) shares = e.get('shares', 0) cost = e.get('cost', 0) if price <= 0: continue # 用 strategy_tree 评估 try: from strategy_tree import evaluate_branches results = evaluate_branches(code, scenario['id'], price, shares, cost) for r in results: if r.get('applicable') and r.get('action_type') != 'hold': is_held = code in pf_codes label = '持仓' if is_held else '自选' alives.append(f" {label} {r.get('action_type','?')} {code}@{price} | 情景{scenario.get('label','')}→{r.get('branch_id','').split('_')[-1]}| {r.get('rationale','')[:30]}") break except Exception: pass if not alives: return 0 # SILENT # 只推单一情景行 + 操作列表 out_lines = [f"【知微】分支扫描 | {scenario.get('label','')}({scenario.get('id','')})"] out_lines.extend(alives) msg = '\n'.join(out_lines) print(msg) push(msg) return 1 if __name__ == '__main__': sys.exit(main())