stale_push_wlin: 推荐加理论仓位+当前建议仓位(基于现金)

每只推荐新增第四行:
  仓位:理论推荐{theo_pct}% | 当前建议{actual_pct}%({N}手≈预算)

仓位计算:
  理论 — 基于RR(8-25%) + 大盘(±20%) + 品种特性(±20%)
  当前 — 理论×多只稀释系数 + 按实际现金计算可买手数
  兜底 — 预算不够1手时推荐至少1手

Dad要求:买卖不能不写仓位,理论仓位不受现金限制,
当前建议仓位根据portfolio.json实际现金计算
This commit is contained in:
知微
2026-06-24 10:00:52 +08:00
parent b30a5fcdde
commit 3ba2b044d7
+65 -7
View File
@@ -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}")