Files
Hermes-Skills/dividend-investing/references/us-bdc-reit-frequency-classification.md
T

9.4 KiB

美股派息频率反推 + BDC/REIT 高息陷阱分类 (2026-08-26)

触发场景: 美股除权日推送 (dividend_alert.py --market us) 出现 10%+ 股息率时, 必然是 BDC (Business Development Company) / REIT / 优先股 类高频派息票 — 真"稳"的高息股年化股息率很少超过 8%。

⚠️ 为什么"年化 / 每股派"是垃圾公式

Nasdaq API 返回两个字段:

  • dividend_Rate = 单次派息 (e.g. $0.04)
  • indicated_Annual_Dividend = 年化派息 (e.g. $0.42)

旧版 dividend_alert.py 用 ann / rate 算"连续派息年数":

  • 季度派: $1.92 / $0.48 = 4 → 4 年 ✓ (还行)
  • 月派: $0.42 / $0.04 = 12 → 12 年 ❌ (实际可能只派了 3 年)
  • 周派 BDC: $12.85 / $0.05 = 257 → 257 年 ❌❌❌ (PSEC 2026-08-26 真值)

公式假设"每股派在历史 N 年都稳定派", 但 BDC 月派/周派是上市后频繁调整 dividend_Rate, 历史派息年数被严重高估。

✅ 正解: ann / rate 反推频率档位, 不要算"连续年数"

freq_n = round(ann / d)
if   freq_n >= 50: freq_str = '🔄周W'      # ≈ 52 次/年 (BDC)
elif freq_n >= 25: freq_str = '🔄双周BW'    # ≈ 26 次/年
elif freq_n >= 11: freq_str = '🔄月M'      # ≈ 12 次/年 (BDC 月派)
elif freq_n >=  5: freq_str = '🔄双月BM'    # ≈ 6 次/年 (优先股)
elif freq_n >=  3: freq_str = '📅季度Q'     # ≈ 4 次/年 (REIT/主流股息 ETF)
elif freq_n ==  2: freq_str = '📅半年S'     # ≈ 2 次/年
elif freq_n ==  1: freq_str = '📅年A'       # ≈ 1 次/年 (成长股)
else:              freq_str = '❓'          # 不规则

🚨 高息陷阱识别清单

看到 🔄W / 🔄BW / 🔄M / 🔄BM 立刻警觉:

频率 票类型 例子 风险
🔄周W (50+) BDC 周派 SATA (12.85%), PSEC dividend 频繁下调, NAV erosion, 实质是 return of capital
🔄双周BW (25-50) BDC 双周 (少见) 同上
🔄月M (11-25) BDC 月派 PSEC (17.87%, 推估值) 月派月调, 长期收益靠股价上涨, 派息率虚高
🔄双月BM (5-10) 优先股 / baby bond PFF 类 ETF 持仓 利率敏感, 久期长
📅季度Q (3-4) REIT / 主流股息 ETF O (Realty Income), MAIN, EPR 相对安全, 但要查 P/FFO 估值
📅半年S (2) 大型 REIT / 蓝筹 KO (可口可乐), JNJ 真"稳"高息
📅年A (1) 成长股 / 一次性 KMDA, 一些 SPAC 不适合靠派息投资

📊 实测对照 (2026-08-26 美股除权推送)

票 每股派 年化 频率 现估连续年数 实际
SATA $0.05 $12.85 🔄周W 🔥249 (公式) BDC 周派, 实际派了 ~5 年
PSEC $0.04 $0.42 🔄月M 🔥12 (公式) BDC 月派, 实际派了 ~10+ 年
KMDA $0.17 $0.25 📅年A 1.5 半年派, 实际派 1-2 年
EMBC $0.01 $0.04 📅季度Q 4 季度派, 公式碰巧对
EXPE $0.48 $1.92 📅季度Q 4 季度派, ✓
SOLS $0.07 $0.30 📅季度Q 4 季度派, ✓

🛠 实现位置

改动文件: ~/.hermes/scripts/dividend_alert.py (cron 跑这份副本, skill 内也同步)

新加列: 美股表格第 4 列从 连续(估年) 改成 频率(估), 把"连续年数"挪到第 5 列。这样用户看推送能立刻分辨 BDC 高频 vs 稳定季度派。

反模式 (不要再写):

  • ❌ 直接显示 连续 (249 年) — SATA 真派了 5 年, 这是公式 bug 严重误导
  • ❌ 用 ann / rate 当 "连续年数" 列给用户看
  • ❌ 月派/周派票当成"稳"推荐给用户

正解:

  • ✅ ann / rate 反推成"频率档位标签" (🔄周W / 🔄月M / 📅季度Q)
  • ✅ 单独把"频率"作为信号列, 不要 单独显示"连续年数"当主要卖点
  • ✅ cron 推送加警告: "W/BW/M/BM 是 BDC/REIT 高频派息(高息陷阱常见)"

📈 进一步改进 (未来, user 没要求)

  • 真连续年数需要 yfinance API (国内 VPS 不稳定, 之前 user 确认不稳)
  • NASDQ dividend history API 也不在中国 VPS 容易访问
  • 短期不修, 等 VPS 网络稳定再考虑

⚠️ 数据源覆盖盲区 (2026-08-26 新发现)

问题: 上面的所有分析都假设 Nasdaq API 能拉到票 — 但很多周派/月派 ETF/BDC 根本不在 Nasdaq 除权日历里。

实测验证 (2026-08-26):

  • 查未来 5 个周四 (8/27, 9/3, 9/4, 9/10, 9/11) → Nasdaq API 累计返回 71 个 symbol
  • 这些 symbol 都是月派/季度派/半年派
  • QQQY / RDTE (典型周派 ETF) → 在 yfinance 历史派息里确实每周四在派 ($0.13-0.22/周), 但 Nasdaq 日历完全看不到它们
  • SATA / PSEC (BDC 周/月派) → 偶尔出现 (如 SATA 在 9/3 出现过一次), 但它们的周派有遗漏

根因猜测: Nasdaq api/calendar/dividends 数据源大概率来自 Nasdaq 上市公司公告 + 第三方数据汇总 (Nasdaq Basic subscription), 周派 ETF 的发款方 (Roundhill, etc.) 未必都接入了这个数据流。

含义:

  • 用户看不到 ≠ 它没派息
  • 推送的"明天除权票"列表 = Nasdaq 收录子集,不是美股完整除权集合
  • 对"我想看本周周派 ETF 派了多少"这个问题,这个脚本回答不了

解决方案 (按 user 偏好从优到劣):

方案 实现成本 准确度 副作用
A. 维护周派 ETF 白名单 + 单独 cron 扫 yfinance 低 中 (yfinance 时不时挂) 漏新发周派 ETF
B. 爬 stockanalysis.com 的 weekly dividend screener 中 高 反爬风险
C. 用 ETF.com API (付费) 高 高 $
D. 退一步: 推送末尾加免责 低 N/A 不解决"想看到"

当前做法 (2026-08-26 user 决定): 先不调 — 推送接受现有数据源 + 末尾明示覆盖盲区。

写入推送末尾的免责 (cron 推送 fixed-footer, 已实装):

⚠️ 频率(估) = round(ann/每股派), 仅反推档位非真历史; W/BW/M/BM 是 BDC/REIT 高频派息(高息陷阱常见)

⚠️ 本数据源 (Nasdaq 除权日历) 不收录全部美股,典型漏: QQQY/RDTE 等周派 ETF。如需追踪,自查 stockanalysis.com weekly dividend screener。


✅ Addendum 2026-08-26: 长桥 MCP 才是正解 (Nasdaq 漏掉的票都能拉)

之前结论错了 — 长桥 MCP 实际有 dividend 工具 (145 个工具之一), 给定 symbol 直接返回该票的完整派息历史, 跟 yfinance 等价, 数据稳定、无反爬。

实测验证 (2026-08-26):

票 Nasdaq API 长桥 MCP dividend 工具
QQQY.US (周派 ETF) ❌ 查不到 ✅ 每周四派, 历史完整 (8/20, 8/13, 8/06...)
RDTE.US (周派 ETF) ❌ 查不到 ✅ 每周四派, 历史完整
PSEC.US (BDC 月派) ⚠️ 偶有遗漏 ✅ 每月派, 历史完整 (10/28, 9/28, 8/27...)
SATA.US (BDC 双周) ⚠️ 偶有遗漏 ✅ 双周派, 历史完整

数据访问路径

Step 1: 用 security_list MCP 工具拿全市场 symbol (US market = 16008 只) Step 2: 调 dividend MCP 工具按 symbol 拉历史派息 Step 3: 本地分类频率档位 (见上文 Python 片段)

实现位置

新脚本 ~/.hermes/scripts/dividend_highfreq.py:

  • --scan: 每日跑, 拉 Top 100 高息 → 批量 dividend → 入 SQLite highfreq_pool 表
  • --alert: 推送"美股高频派息雷达"表
  • --list: 看入库历史

关键架构决策 (用户拍板 2026-08-26)

决策点 选 不选 理由
数据源 长桥 MCP (官方) yfinance / 白名单 / 爬虫 稳定/官方/无反爬/145 工具
候选池范围 Top 100 (TTM div ≥ $2) 全市场 16008 只 cron 时延可控 + 覆盖 90% 高息
频率分类依据 历史派息日期差平均天数 ann/rate 比例 更准 (避免 BDC 高估)
入库 增量合并到 highfreq_pool 全量替换 历史连续性保留
推送 按 freq 排序 + yield + 稳定度 按 yield 单维度 周派 > 月派 > 季度派优先显示

Cron 设计

时间 (北京) 任务 理由
04:00 dividend_highfreq.py scan 离线时段, 不抢长桥 quota
21:00 dividend_highfreq.py alert 21:30 长桥推送前 30 分钟, 顺路追加到 dividend_alert.py 推送末尾

⚠️ screener_search 的限制 (踩坑记录)

虽然长桥有 screener_search 工具, 但 dividend / dpseps 这俩 filter 字段返回 None (server 不暴露真实值)。正确做法: 用 security_list 拿 symbol → 循环 dividend 工具 → 自己算 yield / freq。不要依赖筛股器派息字段。

长桥 MCP 接入 (OAuth) 路径

完整 6 步 OAuth 流程 + /agent 端点替代路径, 见 mcp/native-mcp/references/longport-mcp-setup-2026-08-26.md + mcp/native-mcp/references/longport-mcp-agent-endpoint-2026-08-26.md。


📌 完整决策链 (从坑到解法)

2026-07-29  旧版: ann/rate 公式推"连续派息年数" 
            → BDC 周派的 SATA 显示"连续 249 年" (垃圾)
2026-08-26  修复: ann/rate 改推"频率档位" (W/BW/M/BM/Q/S/A)
            → 显示"🔄周W" + 警告"高息陷阱常见"
            → cron 推送末尾免责说明 Nasdaq 漏 QQQY/RDTE
2026-08-26 (同日) 用长桥 MCP 验证 QQQY/RDTE → 实际能拉到历史派息
            → 推翻"先不调"决定, 改用长桥 MCP 动态扫描
            → 新脚本 dividend_highfreq.py 实现

教训: 不要在第一次找不到解决方案时就放弃 — 多源 (官方 MCP / yfinance / screener) 试一遍, 经常有意外解法。