diff --git a/scripts/stale_push_wlin.py b/scripts/stale_push_wlin.py index 78478c7..38b4db9 100644 --- a/scripts/stale_push_wlin.py +++ b/scripts/stale_push_wlin.py @@ -278,8 +278,62 @@ def main(): except Exception: pass - # 标准格式:每个可操作标的 — 大盘/行业/个股三面+消息/基本面/技术面 - lines.append(f"【💡 操作建议】(当前{len(actionable)}只自选可操作)") + # 仓位计算 + n = len(actionable) + def calc_positions(code, price, lot_cost, rr, market_factor, cat): + # 理论推荐仓位(基于RR+市场+品种特性) + if rr >= 5: + theo_pct = 25 + elif rr >= 3: + theo_pct = 18 + elif rr >= 2: + theo_pct = 12 + else: + theo_pct = 8 + if "偏弱" in market_factor: + theo_pct = int(theo_pct * 0.8) + elif "偏强" in market_factor: + theo_pct = int(theo_pct * 1.15) + if cat in ("蓝筹", "白马"): + theo_pct = int(theo_pct * 1.2) + elif cat in ("题材", "短线"): + theo_pct = int(theo_pct * 0.6) + elif cat in ("高波动", "成长"): + theo_pct = int(theo_pct * 0.85) + theo_pct = max(5, min(30, theo_pct)) + + # 当前推荐仓位(基于实际现金) + # 可操作多只时,每只分配比例降低 + if n >= 5: + share_pct = theo_pct * 0.5 + elif n >= 3: + share_pct = theo_pct * 0.7 + elif n >= 2: + share_pct = theo_pct * 0.85 + else: + share_pct = theo_pct + share_pct = max(5, min(theo_pct, share_pct)) + + budget = cash * share_pct / 100 + lots = int(budget / lot_cost) if lot_cost > 0 else 0 + if lots == 0 and lot_cost > 0 and budget > 0: + # 预算不够1手 → 推荐至少1手 + lots = 1 + actual_pct = round(lots * lot_cost / cash * 100) if cash > 0 else 0 + else: + actual_pct = round(lots * lot_cost / cash * 100) if cash > 0 else 0 + + if lots == 0: + lots_display = "预算不足1手" + elif budget < lot_cost and lots == 1: + lots_display = f"至少{lots}手" + else: + lots_display = f"{lots}手" + + return theo_pct, actual_pct, lots_display, lots * lot_cost + + # 标准格式:每个可操作标的 — 大盘/行业/个股三面 + 仓位 + lines.append(f"【💡 操作建议】(当前{n}只自选可操作 | 现金{cash:,.0f}元)") for s in actionable: name, code, price, buy_low, buy_high, lot, ratio = s d = code_data.get(code, {}) @@ -289,9 +343,9 @@ def main(): sig = d.get("timing_signal", "") sector = d.get("sector_context", "") tech = d.get("tech_snapshot", "") - factors = d.get("signal_factors", []) - cat = d.get("stock_category", "") note = d.get("note", "") + d_factors = d.get("signal_factors", []) + cat = d.get("stock_category", "") # 提取技术位 ss = {"强撑":"-", "弱撑":"-", "弱压":"-", "强压":"-"} @@ -307,9 +361,9 @@ def main(): pe_str = f"PE{pe:.0f}" if pe else "" eps_str = f"EPS{eps:.2f}" if eps else "" - # 从 signal_factors 或 tag 提取各维度 + # 从 signal_factors 提取各维度 def _match_factor(prefix): - for f in factors: + for f in d_factors: if f.startswith(prefix): return f return "" @@ -335,12 +389,16 @@ def main(): analysis = " | ".join(p for p in parts if p) + # 仓位计算 + theo_pct, actual_pct, lots_display, lots_cost_total = calc_positions(code, price, lot, rr, market_factor, cat) + pfx = "" if len(code) == 6 else "HK$" lines.append( f" {name}({code}) {pfx}{price:.2f} 买区{buy_low}~{buy_high} | " f"1手{lot:,.0f}元 RR={rr:.1f} 损{sl} 盈{tp}\n" f" {analysis}\n" - f" 技术{ss['强撑']}→{ss['弱撑']}→{ss['弱压']}→{ss['强压']} | 信号{sig}" + f" 技术{ss['强撑']}→{ss['弱撑']}→{ss['弱压']}→{ss['强压']} | 信号{sig}\n" + f" 仓位:理论推荐{theo_pct}% | 当前建议{actual_pct}%({lots_display}≈{lots_cost_total:,.0f}元)" ) lines.insert(0, f"【知微】自选买入提醒 {now} | 现金{cash:,.0f}元")