6维评分通用模块 + 港股通T+2延迟标注
1. stock_scorer.py — 共享的6维评分模块
- score_future_outlook(code, data) → (score, reasons)
- rank_by_outlook(holdings, data) → 排序列表
- settlement_delay_note(sell_code, buy_code) → 结算延迟说明
- is_hk_stock(code) → 判断港股通标的
2. stale_push_wlin.py 改用共享模块(去掉本地函数定义)
3. 换仓评估增加港股通结算延迟检测:
- 卖港股→买A股时标注⚠️T+2到账限制
- 本次推荐(招商银行+A股→海博思创)无需标注,全是A股
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
#!/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
|
||||
|
||||
|
||||
def is_hk_stock(code):
|
||||
"""判断是否为港股(港股通标的代码通常5位)"""
|
||||
return len(str(code)) <= 5
|
||||
|
||||
|
||||
def is_a_stock(code):
|
||||
"""判断是否为A股(6位代码)"""
|
||||
return len(str(code)) == 6
|
||||
|
||||
|
||||
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 ""
|
||||
Reference in New Issue
Block a user