Files
Hermes-Skills/dividend-scanner/SKILL.md
T

277 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: dividend-scanner
description: 高息股扫描与DCA监控系统 - 三市场(港股/美股/A股)自动扫描候选、监控持仓买入信号
trigger: DCA监控、高息扫描、股息率筛选、dividend scan、阶梯买入
---
# 高息股扫描与DCA监控
## 系统架构
```
~/.hermes/scripts/
├── lib/ # 公用库 (2026-08-23+)
│ ├── __init__.py
│ └── td9.py # 神奇九转 TD Sequential (4 个脚本共享)
├── dividend_alert.py # 股息登记日前一天提醒(A/HK/US三市场,无Token依赖)
├── cn_dividend_buy_timing.py # A股每日买入时机(11:30 BJT 推送,加权技术指标增强)
├── cn_dividend_buy_timing_cron.sh
├── dca_scanner.py # 港股/美股周扫描(LongPort API)
├── scan_cn.py # A股周扫描(LongPort价格+预设股息率)
├── dca_monitor.py # 持仓监控(买入信号),支持 --market=us/hk/cn
├── dca_positions.json # 持仓配置(含阶梯价位、股息率、派息频率)
├── scan_hk.sh # shell包装脚本
├── scan_us.sh
├── scan_cn.sh
├── dca_monitor_us.sh # DCA美股监控wrapper(解决no_agent参数问题)
├── rgti_alert.py # RGTI价格提醒
├── rgti_auto_monitor.py # RGTI半自动做T挂单
└── rgti_alert_state.json
```
## 股息登记日提醒系统(dividend_alert.py)
### 用途
每天自动扫描**明天除权的股票**,在登记日前一天推送给用户,让用户有足够的买入时间窗口。
### 数据源(无需API Key)
| 市场 | 数据源 | 函数/API |
|------|--------|----------|
| 🇨🇳 A股 | AKShare(百度) | `ak.news_trade_notify_dividend_baidu(date='YYYYMMDD')` |
| 🇭🇰 港股 | AKShare(百度) | 同上(交易所=HK) |
| 🇺🇸 美股 | Nasdaq API | `https://api.nasdaq.com/api/calendar/dividends?date=YYYY-MM-DD` |
### 数据格式说明
**A股/港股(百度接口):**
- `分红`字段已经是 **元/10股** 或 **港元/10股**,不要乘以10
- 返回字段:股票代码, 除权日, 分红, 送股, 转增, 交易所, 股票简称, 报告期
- A股除以权除息日查询,登记日=除权日的前一个交易日
- 可以查未来日期,支持周末自动跳过
**美股(Nasdaq API):**
- `dividend_Rate`: 本次每股分红金额(美元)
- `indicated_Annual_Dividend`: 年化分红
- `record_Date`: 登记日(美股登记日通常=除权日)
- 优先股/REIT占多数,注意区分
- **⚠️ 重要坑 (2026-09-01 用户纠正)**: `indicated_Annual_Dividend` (ann) 是 **Nasdaq 估算的"未来一年总派息额"** (单位 USD, **不是百分比, 不是股息率**)。
- **反推频率档位** = `round(ann / dividend_Rate)` ≈ 一年派几次 → 4=季度(Q) / 12=月(M) / 52=周(W) / 2=半年(S) / 1=年(A)
- **这个数字不是"连续派了几年"**, 旧列名"连续(估年)" = "一年派几次的档位数字" 是误导, **2026-09-01 已改名为"频率(反推)"**, **"年化"已改名为"估算年派"**
- **ann=0 时** = Nasdaq 数据缺失, 频率档位显示 "⚠️数据缺失", 不归入档位
- 周派票实测 (SATA ann=$12.85, dividend_Rate=$0.05 → 12.85/0.05=257 ≈ 5 trading days × 52 weeks ≈ 260 ✓ 反推逻辑能识别周派)
### 实现要点
- **proxy处理**:服务器在EDT时区,请求国内API需先 `unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY`,否则Python requests走127.0.0.1:7890代理会报ProxyError
- **时间处理**:北京时间运行,用 `datetime.utcnow() + timedelta(hours=8)` 转换
- **周末跳过**:`while d.weekday() >= 5: d += timedelta(days=1)`
- **no_agent模式**:cron任务用 `no_agent=True`,脚本stdout直接推送给用户,不需要LLM推理
- **输出格式**:emoji标记+分类(A/HK/US三栏),每行一个股票+分红金额+除权日期
### Cron配置
```
30 20 * * 1-5 # EDT 20:30 = 北京 次日 8:30 AM
# Mon 20:30 EDT → Tue 08:30 BJT (查Wed除权)
# Thu 20:30 EDT → Fri 08:30 BJT (查Mon除权,跳过周末)
```
### 使用方式
用户看到推送后,**当天开盘买入**仍能赶上登记日,享有本次分红权。
## 高息股扫描 vs 股息登记日提醒(区别)
| 维度 | 高息扫描 | 分红提醒 |
|------|---------|---------|
| 时机 | 每周五收盘后 | 每天 20:30 EDT |
| 目的 | 长期候选池价格监控 + DCA建仓 | 明日除权提醒 |
| 输出 | 当前价、股息率、涨跌、阶梯买入点 | 明天除权的股票 + 预计股息率 |
| 动作 | 关注买入机会 | 提醒买入搭车分红 |
| 数据源 | LongPort实时报价 | AKShare除权日历 + Nasdaq |
| 池子 | 固定候选池(~24只港股/15只美股/20只A股) | 全市场除权数据 |
**不重复,互补关系。** 扫描说"这票便宜可以囤",提醒说"明天发钱今天上车"。
## Cron任务配置
| 任务 | 时间(EDT) | 北京时间 | 频率 | 脚本 |
|---|---|---|---|---|
| 港股高息扫描 | 周五 20:00 | 周六 8:00AM | **每周五** | scan_hk.sh |
| A股高息扫描 | 周五 19:30 | 周六 7:30AM | **每周五** | scan_cn.sh |
| 美股高息扫描 | 周五 21:30 | 周六 9:30AM | **每周五** | scan_us.sh |
| 美股盘中监控(夜间) | 22:30 | 10:30AM | 工作日 | dca_monitor_us.sh |
| 美股盘中监控(凌晨) | 02:00 | 14:00 | 工作日 | dca_monitor_us.sh |
| **股息登记日前一天提醒** | **20:30** | **次日8:30AM** | **每天** | **dividend_alert.py** |
> 📌 高息扫描已从每天改为每周五收盘后推送,分红提醒保持每天不变。扫描是"哪些高息股现在值得买",提醒是"明天分红今天买入"。
## 用户偏好(关键)
1. **吃股息为主,但入场时机可加技术指标 (2026-08-23 修正)**: 用户原话"高股息扫描的也要结合这个指标(九转)"。**修正**: 之前默认"不做技术面分析"的规则只适用于"分析分红/历史股息率/CAGR"这一类查询。**入场时机判别**(`cn_dividend_buy_timing.py` 的 🟢🟡🔴 决策)可以叠加 TD9 增强(避免在涨势到顶时买入),但仍以股息率 + MA50 + 支撑为底层决策依据,TD9 只是**信号增强层**。
2. **时间显示用北京时间(UTC+8)**,不要用服务器EDT时间。
3. **输出格式**:emoji标记 + 简洁卡片状,数据密集但视觉清爽,≤500字。
## 🧙 技术指标增强层:神奇九转 (TD Sequential)
**仅作用于入场时机判别**, 不替代股息率 / MA50 / 支撑等基础条件。
### 入场增强规则 (cn_dividend_buy_timing.py)
| TD9 状态 | 对入场判别的影响 |
|---|---|
| 买入计数 ≥7 (未完成, 跌势末期) | 🟢今天买 理由加 "+ 🧙九转买 N/9 (跌势末期)" |
| 卖出计数 ≥7 (未完成, 涨势末期) | 🟢今天买 理由加 "⚠️🧙九转卖 N/9 (涨势末期,回撤将至)" |
| **卖出完成 (done=True, 涨势到顶)** | 🔴不入场 **升级为 🟡等回撤 ★★☆,止损用九转止损价 (第9根收盘)** |
| 买入计数 <5 或 无九转信号 | 不影响原判别 |
### 周扫描输出 (scan_cn.py / dca_scanner.py)
阶梯入场表后加两行:
```
| 🧙 九转 | 多 九转买… 6/9 | 空 九转卖✓ 11/9 | - 九转… 0/9 |
| 🧙 止损 | - | 44.70 | - |
```
### 公用库抽取 (2026-08-23)
`td9_levels()` 抽到 `~/.hermes/scripts/lib/td9.py`, **4 个脚本共享**:
```
~/.hermes/scripts/lib/td9.py
├── td9_levels(closes, current) → dict or None
└── td9_summary(td9) → str (短字符串用于表格 cell)
```
**禁止** 在任何脚本里复制 `td9_levels()` 本地实现 — 修改算法只改 `lib/td9.py`, 4 个脚本自动同步。
详见 `intraday-trading/references/td9-td-sequential.md` (算法 + 单元测试 + 输出格式 + 4 脚本用法)。
## 关键实现细节
### `dividend_highfreq.py` — 美股高频派息扫描 (2026-08-26 v1.0 实装 + cron 接入)
详见 `references/us-dividend-frequency-tier.md` v2 节。设计: `security_list` 拿全 US 市场 → `quote` 批量拿现价 → `dividend` 逐只算频率档位 → yield ≥ 4% 入 SQLite `highfreq_pool` → 按 freq+yield+稳定度推送。**取代了 v1 时期 "Nasdaq 不收周派" 的限制**。
**实际跑 (2026-08-26)**:
- 候选池: security_list US 翻页 5 页 → 244 只 (跳过优先股/WARRANT/WTS)
- batch quote 50/批 → 244/244 拿到现价
- dividend 逐只 (1-4s/只) → 29 只 yield ≥ 4% 且 cv<0.5 入池
- 总耗时 ~6 分钟 (cron 可接受)
**Cron job**: `b29af10da8d2` ("美股高频派息雷达"), schedule `30 21 * * 1-5` 北京, no_agent + script 模式, deliver origin.
**v1.0 实战发现的 YieldMax 票** (CRY/BIOY/XEY/TECY/TSYY 全部 yield>50% 但 cv<0.2 = 真实稳定高息, 不是 bug): 推送时**必须**带"文化娱乐参考, 不构成投资建议" disclaimer + cv 列 + ⭐⭐⭐ 评级让用户自己判断风险. 详见 `native-mcp/references/longport-mcp-tools-pitfalls.md` Pitfall 11.
**lib/td9.py 接口不匹配 bug (2026-08-26 发现, 待修)**: `td9_levels(closes)` 返回 list, 但 `td9_summary(td9)` 期望 dict → 调用就抛 `TypeError: list indices must be integers or slices, not str`. 修复方向: td9_summary 改成 `td9_summary(td9_list, current_price=None)` 接受 list, 或 td9_levels 改成返 dict. **不要绕过** (`td9_levels` 在 4 个脚本共享, 改签名影响面大).
### Shell包装脚本(必须)
Cron的script字段不能带参数。Python脚本需要参数时,用.sh包装:
```bash
#!/bin/bash
cd /home/openclaw/.hermes/scripts
python3 dca_scanner.py hk
```
Cron系统对.sh文件自动用bash执行,不需要chmod +x。
### A股数据源
- **LongPort有CN行情**:`ctx.quote(["601088.SH"])` 可以获取A股实时价格
- **东方财富API**:从美国服务器无法直连,需走Mihomo代理(127.0.0.1:7890),且不稳定
- **股息率**:LongPort的CalcIndex.DividendYield对A股可能不可靠,用预设数据更稳
- **股票名称**:东方财富API的f14字段可能返回代码而非名称,必须用name_map兜底
### 输出格式(用户偏好)
```
🥇 冀中能源 [煤炭]
000937.SZ
💰 现价: 5.28 📉 -2.9%
📊 股息率: 11.0% 派息: 年度
🪜 阶梯: T1:5.12(-3%) → T2:4.96(-6%) → T3:4.75(-10%)
```
- emoji标记 + 简洁一行一个信息
- 阶梯买入价:现价的-3%/-6%/-10%
- 总字数≤500
### 市场过滤(dca_monitor.py)
`--market=us` 参数按positions.json的market字段过滤。无参数则监控全部。
## 候选股池
### 港股(≥7%股息率)
银行:建行/工行/农行/中行
能源:中海油/中国神华/中石油
REIT:领展/顺丰房托/置富/越秀/冠君
电信:中国移动/香港电讯
### 美股(≥7%股息率)
BDC:ARCC/HTGC/PSEC/MAIN/ABR/OFS
mREIT:NLY/AGNC/TWO/CIM/NYMT/STWD
其他:SBR/PDI/PTY
### A股(≥5%股息率)
煤炭:冀中能源/中国神华/平煤股份
白酒:洋河/五粮液/泸州老窖/古井贡/茅台
银行:交行/工行/建行/农行/中行/兴业/光大
其他:宁沪高速/浙能电力/长江电力
## Pitfalls
1. **全量脚本同时失败=Token过期**:港股/美股/A股三市场扫描+DCA监控全部报401003错误时,不要逐个排查。**100%是LongPort access token过期**。快速诊断:`cd ~/.hermes/scripts && bash scan_hk.sh`,看是否返回 `code=401003 token expired`。修复:去 [LongPort开发者后台](https://open.longportapp.com/) 刷新Token。
2. **Token截断(401004)**:`.bashrc` 中 `LONGBRIDGE_ACCESS_TOKEN=m_eyJh...jb-k` 可能是占位符(中间有`...`)。此时报错是401004而非401003。权威token在 `~/.env`。
3. **API限流**:多个脚本同时调LongPort会触发429002错误。避免10分钟内的高频轮询。
4. **USOption权限**:LongPort返回"You do not have access to USOption"不影响正股数据。
5. **A股名称**:东方财富f14字段不可靠,必须维护name_map。
6. **代理依赖**:东方财富API从美国服务器不稳定,A股扫描优先用LongPort。
7. **用户不喜欢轮询**:最低30分钟间隔。
8. **无候选时不推送(2026-06-24)**:`dca_scanner.py` 的 `format_result()` 在无符合条件的标的时返回空字符串,主程序过滤空输出不print。`no_agent: true` 任务无stdout=不推送。避免用户收到"暂无符合条件的标的"的空消息。
9. **Proxy冲突**:服务器 `HTTP_PROXY=http://127.0.0.1:7890` 环境变量是全局的。Python requests 自动读取,导致国内 API 请求失败(ProxyError)。**所有国内 API 调用前必须先 unset proxy**:`os.environ.pop('http_proxy', None)` 等四个变量都要清。美股 Nasdaq API 直连无此问题。
10. **百度接口港股过滤**:返回数据的 `交易所` 字段,HK=港股、SH/SZ/BJ=A股。注意港股代码前有空格(如 ` 06808`),需要 `strip()`。
11. **除权日与登记日关系**:A股登记日=除权日前一交易日。美股登记日通常=除权日当天。
12. **百度接口日期格式**:`news_trade_notify_dividend_baidu(date='YYYYMMDD')` 参数是纯数字字符串,不要带横杠。支持查未来日期。
13. **🧙 九转公用库禁止复制粘贴 (2026-08-23)**: 4 个扫描脚本 (`cn_dividend_buy_timing.py` / `scan_cn.py` / `dca_scanner.py` / `daily_t_analysis.py`) 都依赖 `~/.hermes/scripts/lib/td9.py`。**禁止** 在脚本里复制 `td9_levels()` 本地实现 — 修改算法只改 `lib/td9.py`, 4 个脚本自动同步。
14. **🧙 九转信号增强只用于入场时机, 不替代股息率 (2026-08-23)**: 用户原话"高股息扫描的也要结合九转", **仅限入场时机判别** (`cn_dividend_buy_timing.py` 的 🟢🟡🔴 决策 + 阶梯入场表)。**不要** 把九转叠加到"分析分红历史/CAGR"这一类查询 — 那是基本面分析, 用 AKShare / 东方财富, 不要技术面。
15. **🧙 九转单元测试先于集成 (2026-08-23)**: 改 `lib/td9.py` 时先在 `/tmp/test_td9.py` 跑 6 个边界 case (连续14跌/14涨/<13根/平盘/振荡/部分跌),确认算法对了再跑全脚本。4 个集成脚本都拉真实 API + proxychains, 慢且依赖重, 调试算法不要每次都拉行情。
16. **⚠️ Nasdaq `indicated_Annual_Dividend` 字段名翻译坑 (2026-09-01 用户纠正)**: 见上文"美股(Nasdaq API)"段, "年化" 不是"年化股息率" 而是"Nasdaq 估算的年度总派息 (USD)", "连续(估年)" 不是"连续派了几年" 而是"反推频率档位的数字"。**列名误导会让用户以为 4.0 = 派了 4 年, 实际 = 一年派 4 次 (季度派)**。已改名为 "估算年派" + "频率(反推)" + 删除 "连续(估年)" 列 (2026-09-01)。
## 股息分析工作流(用户问"买点"时)
当用户说"分析XX的买点"时,**先区分是吃股息分析还是入场时机判别**:
### 吃股息分析 (历史/分红/CAGR)
用户原话指向"看分红能力/可持续性"时, 走这条路径:
1. **查分红历史** → `ak.stock_history_dividend_detail(symbol)` 拿历年数据
2. **算当前股息率** → 每股分红 / 当前股价
3. **算分红增长率** → 5年CAGR、同比变化
4. **查除权时间线** → 已除权还是未除权?最近一次除权日即已错过,等下一波
5. **查盈利预测** → EPS 看分红可持续性(分红率=每股分红/EPS)
6. **查财务健康** → 货币资金、经营现金流(确保有钱分红)
7. **避坑**:不要给 MACD/均线/支撑阻力等纯技术面分析
### 入场时机判别 (cn_dividend_buy_timing.py)
用户原话指向"今天能不能买/什么时候买"时, 走 `cn_dividend_buy_timing.py` 流程:
1. 拉 K 线 50 根 → 算 MA50 / 支撑 / 趋势 / ATR
2. 跑 **🧙 九转** (`td9_levels`) 作为信号增强层
3. `recommend_entry()` 综合判别 → 🟢今天买 / 🟡等回撤 / 🔴不入场
4. **TD9 卖出完成时** → 🔴升级为 🟡等回撤 + 用九转止损价
5. **TD9 买入计数 ≥7** → 跌势末期加分提示
详见上文"🧙 技术指标增强层"小节。
### 输出格式(吃股息卡片)
```
💰 XX年全年分红: XX元/10股 = X.XX元/股
📊 当前价格: XX.XX元 (除权后)
📊 股息率: X.XX%
📈 X年股息CAGR: X.X%/年
```
## 参考资料
- `references/us-dividend-frequency-tier.md` — 美股频率档位反推实战 (Nasdaq API ann 字段翻译 + YieldMax 高息陷阱)
- `references/cn-top8-auto-screen.md` — **A 股 Top N 自动筛 v1-v4** (2026-09-17, 已废) — 财年滚动算法 + 含预案 ≈ 同花顺 7.44% (历史记录, 算法验证路径)
- `references/cn-top8-weekly-batch-v5-ths-parallel.md` — **A 股 Top N 自动筛 v5 生产版** (2026-09-19 实装, **当前用这个**) — 东方财富 batch 粗筛 + 同花顺 ths 8 线程并行校验 + JSON 缓存 + 25 秒跑完 Top 8. cron 集成计划 (每周一 + 读缓存). **核心教训**: agent 算法永远追不上同花顺专业团队 → 直接用同花顺接口拿数据 (用户原话 "你一个AI写算法还能比得过专家吗").