feat: 迁移 trading 相关脚本到 skill 仓库 (第2批: 🟡 中优先级)
【迁移内容】
- dividend-investing/scripts/dca_monitor.py + dca_monitor_us.sh
- dividend-scanner/scripts/scan_cn.{py,sh} + scan_hk.sh + scan_us.sh
- okx-auto-position/scripts/signal_queue_retry.sh
- lottery-hk/scripts/verify_lottery.sh
- longbridge-cli/scripts/longport_http.py (公共模块)
【配套修改】
- 5 个 cron 任务 script 路径更新 (jobs.json):
- 8929ca09 (DCA港股上午) → dividend-investing/scripts/dca_monitor.py
- 9469c128 (DCA港股下午) → dividend-investing/scripts/dca_monitor.py
- 3a4bef2c (DCA美股凌晨) → dividend-investing/scripts/dca_monitor_us.sh
- a82a3ab0 (signal-queue-retry) → okx-auto-position/scripts/
- b4868849 (lottery-verify-result) → lottery-hk/scripts/
【删除】本地 ~/.hermes/scripts/{dca_monitor,scan_*,signal_queue_retry,verify_lottery,longport_http}
【未迁移】scan_cn/hk/us 仍需挂 cron, 暂不删 (走 scanner skill)
This commit is contained in:
Executable
+127
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
A股高股息扫描器(LongPort取价 + 预设股息率)
|
||||
"""
|
||||
import os, sys, json
|
||||
from datetime import datetime
|
||||
|
||||
# === 读取LongPort环境变量 ===
|
||||
bashrc = open(os.path.expanduser("~/.bashrc")).read()
|
||||
for line in bashrc.splitlines():
|
||||
if line.startswith("export LONGPORT_") or line.startswith("export LONGBRIDGE_"):
|
||||
parts = line.replace("export ", "").split("=", 1)
|
||||
if len(parts) == 2:
|
||||
os.environ[parts[0]] = parts[1].strip('"').strip("'")
|
||||
|
||||
from longport import openapi
|
||||
cfg = openapi.Config.from_env()
|
||||
ctx = openapi.QuoteContext(config=cfg)
|
||||
|
||||
# === A股候选池 ===
|
||||
A_SHARE_POOL = {
|
||||
"601088.SH": {"name": "中国神华", "yield": 6.7, "freq": "年+中期", "sector": "煤炭"},
|
||||
"601328.SH": {"name": "交通银行", "yield": 6.2, "freq": "年度", "sector": "银行"},
|
||||
"601398.SH": {"name": "工商银行", "yield": 5.9, "freq": "年度", "sector": "银行"},
|
||||
"601288.SH": {"name": "农业银行", "yield": 5.8, "freq": "年度", "sector": "银行"},
|
||||
"601939.SH": {"name": "建设银行", "yield": 6.0, "freq": "年度", "sector": "银行"},
|
||||
"601988.SH": {"name": "中国银行", "yield": 5.7, "freq": "年度", "sector": "银行"},
|
||||
"600900.SH": {"name": "长江电力", "yield": 3.8, "freq": "年度", "sector": "电力"},
|
||||
"601857.SH": {"name": "中国石油", "yield": 5.5, "freq": "年度", "sector": "能源"},
|
||||
"600028.SH": {"name": "中国石化", "yield": 5.2, "freq": "年度", "sector": "能源"},
|
||||
"601728.SH": {"name": "中国电信", "yield": 4.8, "freq": "年度", "sector": "电信"},
|
||||
"600036.SH": {"name": "招商银行", "yield": 4.5, "freq": "年度", "sector": "银行"},
|
||||
"601166.SH": {"name": "兴业银行", "yield": 5.8, "freq": "年度", "sector": "银行"},
|
||||
"601818.SH": {"name": "光大银行", "yield": 5.9, "freq": "年度", "sector": "银行"},
|
||||
"600377.SH": {"name": "宁沪高速", "yield": 6.2, "freq": "年度", "sector": "高速"},
|
||||
"601666.SH": {"name": "平煤股份", "yield": 6.2, "freq": "年度", "sector": "煤炭"},
|
||||
"600023.SH": {"name": "浙能电力", "yield": 5.5, "freq": "年度", "sector": "电力"},
|
||||
"000858.SZ": {"name": "五粮液", "yield": 10.5, "freq": "年度", "sector": "白酒"},
|
||||
"000568.SZ": {"name": "泸州老窖", "yield": 7.0, "freq": "年度", "sector": "白酒"},
|
||||
"000937.SZ": {"name": "冀中能源", "yield": 11.0, "freq": "年度", "sector": "煤炭"},
|
||||
"002304.SZ": {"name": "洋河股份", "yield": 10.8, "freq": "年度", "sector": "白酒"},
|
||||
"000596.SZ": {"name": "古井贡酒", "yield": 6.9, "freq": "年度", "sector": "白酒"},
|
||||
"000001.SZ": {"name": "平安银行", "yield": 5.4, "freq": "年度", "sector": "银行"},
|
||||
"600519.SH": {"name": "贵州茅台", "yield": 5.0, "freq": "年+中期", "sector": "白酒"},
|
||||
}
|
||||
|
||||
|
||||
def scan_a_share():
|
||||
min_yield = 5.0
|
||||
tickers = list(A_SHARE_POOL.keys())
|
||||
all_quotes = {}
|
||||
|
||||
# LongPort批量获取A股价格
|
||||
for i in range(0, len(tickers), 15):
|
||||
batch = tickers[i:i+15]
|
||||
try:
|
||||
quotes = ctx.quote(batch)
|
||||
for q in quotes:
|
||||
all_quotes[q.symbol] = {
|
||||
"price": float(q.last_done),
|
||||
"prev_close": float(q.prev_close),
|
||||
}
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
results = []
|
||||
for sym, info in A_SHARE_POOL.items():
|
||||
if info["yield"] < min_yield:
|
||||
continue
|
||||
q = all_quotes.get(sym)
|
||||
if q and q["price"] > 0:
|
||||
change_pct = (q["price"] - q["prev_close"]) / q["prev_close"] * 100 if q["prev_close"] else 0
|
||||
price = q["price"]
|
||||
else:
|
||||
# LongPort没拿到价格,用预设
|
||||
price = 0
|
||||
change_pct = 0
|
||||
|
||||
results.append({
|
||||
"symbol": sym, "name": info["name"],
|
||||
"price": price, "change_pct": change_pct,
|
||||
"yield": info["yield"], "freq": info["freq"],
|
||||
"flag": "🇨🇳", "sector": info["sector"],
|
||||
})
|
||||
|
||||
results.sort(key=lambda x: x["yield"], reverse=True)
|
||||
return results[:10]
|
||||
|
||||
|
||||
def calc_ladder(price):
|
||||
return [
|
||||
{"tier": 1, "pct": -3, "price": round(price * 0.97, 2)},
|
||||
{"tier": 2, "pct": -6, "price": round(price * 0.94, 2)},
|
||||
{"tier": 3, "pct": -10, "price": round(price * 0.90, 2)},
|
||||
]
|
||||
|
||||
|
||||
def format_result(results):
|
||||
now = datetime.now().strftime("%Y-%m-%d %H:%M")
|
||||
if not results:
|
||||
return f"🇨🇳 A股高息扫描 | {now}\n\n暂无符合条件的标的(≥5%)"
|
||||
|
||||
lines = [f"🇨🇳 A股高息TOP | {now}", ""]
|
||||
for i, r in enumerate(results, 1):
|
||||
medal = ["🥇", "🥈", "🥉", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣", "🔟"][min(i-1, 9)]
|
||||
lines.append(f"{medal} {r['name']} [{r['sector']}]")
|
||||
lines.append(f" {r['symbol']}")
|
||||
if r["price"] > 0:
|
||||
chg = "📈" if r["change_pct"] >= 0 else "📉"
|
||||
lines.append(f" 💰 现价: {r['price']:.2f} {chg} {r['change_pct']:+.1f}%")
|
||||
else:
|
||||
lines.append(f" 💰 价格: 盘后/未获取")
|
||||
lines.append(f" 📊 股息率: {r['yield']:.1f}% 派息: {r['freq']}")
|
||||
if r["price"] > 0:
|
||||
ladder = calc_ladder(r["price"])
|
||||
lstr = " → ".join([f"T{l['tier']}:{l['price']:.2f}({l['pct']}%)" for l in ladder])
|
||||
lines.append(f" 🪜 阶梯: {lstr}")
|
||||
lines.append("")
|
||||
|
||||
lines.append("━━━━━━━━━━━━━")
|
||||
lines.append(f"📋 共扫描 {len(A_SHARE_POOL)} 只,筛出 {len(results)} 只")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
results = scan_a_share()
|
||||
print(format_result(results))
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
cd /home/openclaw/.hermes/scripts
|
||||
python3 scan_cn.py
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
cd /home/openclaw/.hermes/scripts
|
||||
python3 dca_scanner.py hk
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
cd /home/openclaw/.hermes/scripts
|
||||
python3 dca_scanner.py us
|
||||
Reference in New Issue
Block a user