#!/usr/bin/env python3 """ stock_scorer.py — 6维股票前景评分系统 用于全面评估持仓或自选股的前景。 评分越低(负数越大)= 前景越差,越值得考虑卖出。 评分越高(正数越大)= 前景越好,越值得持有或买入。 使用场景: - 换仓评估(决定卖什么) - 持仓审查(定期排名) - 组合优化(识别需清理的票) 调用方式: from stock_scorer import score_future_outlook score, reasons = score_future_outlook(code, decisions_dict) # 批量评估 from stock_scorer import rank_by_outlook rankings = rank_by_outlook(portfolio_holdings, decisions_dict) """ def score_future_outlook(code, decisions_data): """6维评分:基于决策系统分析数据评估股票前景。 评分维度(按重要度排序): 1. timing_signal — 决策系统主信号(买入/持有/深套持有) 2. 技术形态 — bearish/bullish/neutral 3. 量价关系 — 买卖盘主导 4. 行业背景 — 板块强弱 5. 盈亏比RR — 预期收益/风险 6. 股票类别 — 蓝筹/深套/题材 Args: code: 股票代码 decisions_data: decisions.json 的 "decisions" 数组或 dict(code→数据) Returns: (score, reasons) — score浮点数,reasons字符串列表 """ # 支持两种输入格式 if isinstance(decisions_data, dict): d = decisions_data.get(code, {}) elif isinstance(decisions_data, list): d = {} for e in decisions_data: if e.get("code") == code: d = e break else: return -999, ["无数据"] if not d: return -999, ["无数据"] score = 0.0 reasons = [] # 1. timing_signal — 最直接的信号 signal = (d.get('timing_signal') or '').strip() if '买入' in signal or '加仓' in signal: score += 3 reasons.append('有买入信号') elif '深套持有' in signal or '弱势持有' in signal: score -= 2 reasons.append('深套/弱势持有') elif signal in ('持有', '') or not signal: score -= 0.5 # 中性偏弱(没有积极信号就是消极信号) reasons.append('无积极信号') # 2. 技术形态 tech = (d.get('tech_snapshot') or '') or '' if '/bearish' in tech: score -= 1.5 reasons.append('技术偏空') elif '/bullish' in tech: score += 1.5 reasons.append('技术偏多') # 3. 量价关系 if '主动卖盘占优' in tech: score -= 1 reasons.append('卖盘主导') elif '主动买盘占优' in tech: score += 1 reasons.append('买盘主导') # 4. 行业背景 sector = (d.get('sector_context') or '') or '' if '大跌' in sector or '偏弱' in sector: score -= 0.5 if '大涨' in sector or '偏强' in sector: score += 0.5 # 5. 盈亏比RR rr = d.get('rr_ratio', 0) or 0 if rr >= 2: score += 1 reasons.append(f'RR{rr:.1f}') elif rr < 1: score -= 0.5 reasons.append(f'RR{rr:.1f}<1') else: reasons.append(f'RR{rr:.1f}') # 6. 股票类别 cat = (d.get('stock_category') or '') or '' if '蓝筹' in cat or '白马' in cat: score += 0.5 elif '深套' in cat or '弱势' in cat: score -= 0.5 return round(score, 1), reasons def rank_by_outlook(holdings_list, decisions_data): """批量评估持仓的前景,返回排序后的列表(最差排前)。 Args: holdings_list: 持仓列表,每项有 code, name, shares, cost, price 等 decisions_data: decisions.json 数据 Returns: 排序后的列表,每项增加了 score, reasons 字段 """ results = [] for h in holdings_list: code = h.get("code", "") if not code: continue score, reasons = score_future_outlook(code, decisions_data) results.append({**h, "score": score, "reasons": reasons}) results.sort(key=lambda x: x["score"]) return results import sys, os sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from mo_models import is_hk_stock, is_a_stock def settlement_delay_note(sell_code, buy_code): """返回资金结算延迟说明(如有)。""" sell_is_hk = is_hk_stock(sell_code) buy_is_hk = is_hk_stock(buy_code) if sell_is_hk and not buy_is_hk: return "(港股通卖出需T+2到账后才能买A股,注意时间差)" return ""