Files
MoFin/scripts/strategy_summary.py
T
知微 7b4826777a 自选股自动重评机制+000850华茂股份全面重评
1. stale_detector新增自选股买入区偏离自动重评:
   - 每轮扫描watchlist_stocks, price偏离买入区中心>15%自动触发per_stock_reassess
   - 之前只标记[STRATEGY_STALE]不输出,改为标记+触发重评两步完成
   - 策略完毕直接输出结果,不再等下次cron通知

2. 000850华茂股份全面重评:
   - 核心价值:纺织是壳,金融股权投资才是核心(国泰海通/广发/徽商银行)
   - PB=0.78破净, 7月3日分红3675万占年净利17.85%
   - 7/16临时股东会催化剂
   - 结论:3.70~3.90区间可建仓1~2%,止损3.50,止盈4.30
   - 修复:之前说'观望不建仓'是错的,低估了破净安全垫

3. watchlist_stocks DB加000850记录
2026-07-07 11:20:04 +08:00

88 lines
2.9 KiB
Python

#!/usr/bin/env python3
"""生成策略评估摘要"""
import json
with open('/home/hmo/web-dashboard/data/decisions.json') as f:
dec = json.load(f)
with open('/home/hmo/MoFin/data/portfolio.json') as f:
pf = json.load(f)
holdings = pf.get('holdings', [])
cash = pf.get('cash', 321271)
hk_rate = 0.867
code_to_h = {h['code']: h for h in holdings}
decisions = dec.get('decisions', [])
hold_entries = [s for s in decisions if s.get('shares', 0) > 0]
wl_entries = [s for s in decisions if s.get('shares', 0) == 0]
hk_total_cny = 0
a_total = 0
for h in holdings:
mv = h['shares'] * h['price']
if h.get('currency') == 'HKD':
hk_total_cny += mv * hk_rate
else:
a_total += mv
total_mv = hk_total_cny + a_total
total_assets = total_mv + cash
position_pct = total_mv / total_assets * 100
weak_count = sum(1 for s in hold_entries if s.get('stock_category') in ('弱势','深套'))
print(f'总市值: {total_mv:.0f} CNY (HK${hk_total_cny:.0f}{a_total:.0f})')
print(f'总资产: {total_assets:.0f} CNY')
print(f'仓位: {position_pct:.1f}% 现金: {cash:.0f}')
print(f'持仓: {len(hold_entries)}只 弱势/深套: {weak_count}只 ({weak_count/len(hold_entries)*100:.0f}%)')
print(f'自选: {len(wl_entries)}只')
print()
print('【持仓详情】')
for s in hold_entries:
code = s['code']
name = s['name']
shares = s['shares']
cost = s.get('cost', 0)
sl = s.get('stop_loss', 0)
tp = s.get('take_profit', 0)
cat = s.get('stock_category', '?')
sig = s.get('timing_signal', '?')
h = code_to_h.get(code)
price = h['price'] if h else 0
if h and h.get('currency') == 'HKD':
mv_val = h['shares'] * h['price'] * hk_rate
else:
mv_val = h['shares'] * h['price'] if h else 0
pl_pct = (price - cost) / cost * 100 if cost else 0
pct = mv_val / total_assets * 100
sl_dist = (price / sl - 1) * 100 if sl > 0 else 0
tp_dist = (tp / price - 1) * 100 if tp > 0 else 0
flags = []
if sl_dist < 5:
if pl_pct > 5:
flags.append('利润保护')
else:
flags.append(f'⚠️近止损({sl_dist:.0f}%)')
if tp_dist < 5 and tp_dist > 0:
flags.append('近止盈')
if cat in ('弱势','深套'):
flags.append(f'[{cat}]')
flag_str = ' '.join(flags) if flags else ''
print(f' {code} {name:10s} ¥{price:>7.2f}{pl_pct:+.1f}% 仓{pct:.1f}% 损{sl}({sl_dist:.0f}%) 盈{tp}({tp_dist:.0f}%) {flag_str}')
print()
print('【自选关注】')
for s in wl_entries:
code = s['code']
name = s['name']
el = s.get('entry_low', 0)
eh = s.get('entry_high', 0)
sl = s.get('stop_loss', 0)
price = s.get('price', 0)
sig = s.get('timing_signal', '?')
in_zone = '✅在买入区' if el and eh and price and el <= price <= eh else ''
print(f' {code} {name:10s} ¥{price:>7.2f} 买区{el}~{eh}{sl} 信号{sig} {in_zone}')