Files
MoFin/deploy/profile-scripts/strategy_summary.py
T

87 lines
2.8 KiB
Python

#!/usr/bin/env python3
"""生成策略评估摘要"""
from mo_data import read_decisions, read_portfolio
from mo_models import get_hk_rate
dec = read_decisions()
pf = read_portfolio()
holdings = pf.get('holdings', [])
cash = pf.get('cash', 321271)
hk_rate = get_hk_rate()
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}')