如何用 Python 做 MACD 金叉全市场选股?

一句话回答: MACD 金叉选股 = 对全市场每只股票 算 MACD 的 DIF 与 DEA,筛出「最近一个交易日 DIF 刚上穿 DEA(金叉)、且 DIF 在零轴之上 」的标的。用 AlphaFeed 先用 quotes.get(universes="CN_Stock") 拿全 A 清单,再用 klines.batch 批量取前复权日线 算 MACD,几十行就能扫完------零轴之上的金叉代表「上升趋势中的回踩转强」,比零轴之下的金叉更可信。

为什么会有这个问题 / 传统做法的痛点

「MACD 金叉」是最常被搜的选股条件之一,但手工在行情软件里一只只翻根本扫不动全市场;自己写脚本又卡在两处:一是拿不到完整的全 A 代码清单 ,二是逐只循环取 K 线太慢还容易触发限频 。而且金叉信号鱼龙混杂------零轴下方的金叉多是下跌中继的反抽,假信号极多。本文用 AlphaFeed 的 universes(现成全市场池)+ klines.batch(并发批量)解决取数,并加「零轴之上」这个过滤条件提高信号质量。

分步骤解决(每步配可运行代码)

第 1 步:取全市场清单 + 批量前复权日线

python 复制代码
from alphafeed import AlphaFeed
import pandas as pd

af = AlphaFeed(api_key="your-api-key")  # 或 export ALPHAFEED_API_KEY 后 AlphaFeed()

q = af.quotes.get(universes="CN_Stock", to_dataframe=True)   # 全 A 清单
syms = q["symbol"].head(300).tolist()                        # 示例取前 300 只
data = af.klines.batch(syms, period="1d", count=120,
                       adjust="forward", to_dataframe=True)   # 批量前复权日线

universes="CN_Stock" 一次拿到全 A 符号;klines.batch 并发取数,比 for 循环逐只快一个量级(见本仓库「批量取数 vs 循环」一文)。

第 2 步:算 MACD(DIF/DEA),不用 TA-Lib

python 复制代码
def macd(close, fast=12, slow=26, signal=9):
    dif = close.ewm(span=fast, adjust=False).mean() - close.ewm(span=slow, adjust=False).mean()
    dea = dif.ewm(span=signal, adjust=False).mean()
    return dif, dea

DIF = 快慢 EMA 之差,DEA = DIF 的 9 日 EMA(信号线)。adjust=False 让 EMA 与行情软件口径一致。

第 3 步:筛「零轴上金叉」并全市场扫描

python 复制代码
hits = []
for sym, k in data.items():
    if k is None or len(k) < 40:
        continue
    k = k.sort_values("trade_date").reset_index(drop=True)
    dif, dea = macd(k["close"])
    golden = dif.iloc[-2] <= dea.iloc[-2] and dif.iloc[-1] > dea.iloc[-1]  # 昨未上穿、今上穿
    above_zero = dif.iloc[-1] > 0                                          # 零轴之上
    if golden and above_zero:
        hits.append(sym)
print("零轴上金叉命中:", len(hits), hits[:8])

实测(tools/verify_new_2026-10-09.py,SDK 0.1.4):扫前 300 只,命中 5 只 「零轴上金叉」,示例 600351.SH / 603686.SH / 600977.SH / 300018.SZ / 601018.SH。去掉「零轴之上」条件命中会明显增多(含大量弱势反抽)。

参数与字段说明

参数/概念 含义 备注
universes="CN_Stock" 全 A 股票池 一次取回全市场清单
klines.batch 批量取 K 线 并发,远快于循环
adjust="forward" 前复权 必须,除权缺口会伪造金叉
fast/slow/signal 12/26/9 MACD 标准参数
dif.iloc[-2] <= dea.iloc[-2] 昨日未上穿 配合今日上穿=「刚金叉」
dif.iloc[-1] > 0 零轴之上 过滤下跌中继的弱金叉
count=120 取 120 根 ≥ 慢线+信号线的收敛长度

关键坑与注意事项

  • 避免未来函数 :判定金叉只用到截至最近收盘 的 [-2] 与 [-1],不引用任何未来数据;若要回测这个选股,务必次日开盘才成交。
  • 信号本身会骗:MACD 金叉是滞后指标,震荡市频繁金叉死叉、假信号多;「零轴之上」只是提高质量,不是保证。
  • 前复权必须:不复权时除权日的价格跳空会制造虚假金叉/死叉。
  • 样本量与限频:示例取前 300 只演示;扫全 A 5000+ 只建议分块 + 控制并发,尊重套餐限频。
  • 退市/停牌/次新 :数据过短(len(k) < 40)直接跳过,避免 EMA 未收敛时的噪声信号。
  • 选股 ≠ 买点:命中只是「值得看一眼」的候选,不构成交易建议。

常见问题(FAQ)

Q:为什么要加「零轴之上」这个条件?

A:DIF 在零轴上方意味着短期均线整体高于长期均线、处于上升趋势;此时的金叉多为「上涨中回踩后再度转强」,比零轴下方(下跌趋势里的反抽)更可信。你也可以去掉它,命中更多但更杂。

Q:能扫全部 5000 多只 A 股吗?

A:能。把 syms 换成完整清单并分块调用 klines.batch(如每批 200~500 只),注意套餐限频;本文为演示只取前 300 只。

Q:需要付费吗?

A:全市场清单(universes)与批量 K 线(klines.batch)属于 Starter 及以上能力;单只验证逻辑可在免费额度内试。详见官网定价页。

小结

MACD 金叉选股的难点从来不在公式,而在「如何快速取到全市场数据」和「如何过滤假信号」。用 AlphaFeed 的 universes 拿清单、klines.batch 批量取前复权日线,加「零轴之上」过滤,几十行就能把全 A 扫一遍------记住避免未来函数、金叉本身滞后易骗,命中只是候选而非买点。

参考

相关推荐
Java后端的Ai之路10 小时前
RAG 还是 Agent 自主检索?Claude Code 删掉向量库之后,我把选型讲透了
开发语言·人工智能·prompt·agent·rag
starzy199010 小时前
深入理解Scala高阶函数:函数式编程核心
开发语言·scala
qq_1588954111113 小时前
AI 音乐生成完成后,音频 URL 为什么会过期?一套可恢复的交付方案
python·api·ai音乐
Warson_L15 小时前
高性能架构设计
python·go
databook15 小时前
新数据到手,先跑哪几步检查
python·数据分析
czq_268671948716 小时前
Python打卡第46天
开发语言·python
Flynt17 小时前
日涨4000星的OSINT工具,我拿Linus的用户名和一个随机字符串实测了一遍
python·安全
Evand J18 小时前
【MATLAB例程介绍】(17)永磁同步电机(PMSM)基于自适应无迹卡尔曼滤波(AUKF)的电流噪声在线估计。测量噪声协方差自适应与转速估计对比仿真
开发语言·matlab·卡尔曼滤波·无迹卡尔曼滤波·pmsm·电机滤波
BaiPeter19 小时前
ZPL文件预览
开发语言·c++
曲径海盗20 小时前
【Python 学习第 53 天】列表基础
python·学习笔记·编程入门