4. 量化筛选模型搭建:基于Python的初筛指标计算与数据获取(yfinance库)

好,咱们进入正题。这一章,说白了就是教你如何用Python把纳斯达克龙头股的数据“拽”下来,然后算出一堆有用的指标。我个人习惯把这一步叫做“数据基建”——地基打不好,后面什么模型都是空中楼阁。

你可能会问:“为什么要自己写代码?同花顺、东方财富不都能看数据吗?”嗯,这里有个关键区别:那些软件给你的是“结果”,而我们想要的是“过程”。你自己写代码,才能完全控制数据怎么清洗、指标怎么计算、参数怎么调整。说白了,主动权在自己手里。

核心思路: 用yfinance库获取免费且相对干净的股票数据,然后基于这些数据计算我们需要的初筛指标。整个过程分为三步:数据获取 → 指标计算 → 结果输出。

4.1 为什么选yfinance?

市面上能拿美股数据的库不少,比如pandas-datareader、alpha vantage、quandl。但我为什么推荐yfinance?原因有三:

  • 免费且稳定: 不需要API Key,直接pip install就能用。我在项目中遇到过好几次alpha vantage突然改政策、限制调用次数的情况,yfinance至今没出过这种幺蛾子。
  • 数据覆盖面广: 历史日线数据、分红、拆股、财务报表,甚至期权链都能拿。对于初筛来说,日线数据完全够用。
  • 社区活跃: 遇到问题,Stack Overflow上一搜一大把解决方案。这一点对新手特别友好。
注意: yfinance的数据源是Yahoo Finance,偶尔会有数据延迟或缺失的情况。比如盘前盘后的数据就不太准。我的建议是:只拿收盘价(Close)和调整收盘价(Adj Close),这两个字段最可靠。

4.2 环境准备与安装

先别急着写代码,把环境搭好。我习惯用Anaconda管理Python环境,但如果你用原生的pip也没问题。

# 安装必要的库
pip install yfinance pandas numpy matplotlib

# 如果你还没装,建议也装上
pip install ta-lib  # 技术指标库,后面会用到

嗯,这里要注意:ta-lib在Windows上安装可能有点麻烦,需要下载whl文件。如果你搞不定,可以用纯Python的替代方案,比如用pandas自己算移动平均线,也不复杂。

4.3 数据获取:从单只股票到批量处理

先拿苹果(AAPL)试试手。我个人习惯先跑通单只股票,再扩展到整个股票池。

import yfinance as yf
import pandas as pd

# 获取苹果的历史数据
aapl = yf.download('AAPL', start='2020-01-01', end='2024-12-31')
print(aapl.head())

跑完这段代码,你会看到一个DataFrame,里面有Open、High、Low、Close、Volume、Adj Close这几列。这就是我们最原始的“原材料”。

但问题来了——我们要筛选的是纳斯达克龙头股,少说也有几十只。难道要一只一只手动下载?当然不是。批量处理才是正解。

# 定义股票列表(这里只是示例,实际名单需要你自己筛选)
tickers = ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'NVDA', 'META', 'TSLA']

# 批量下载数据
data = yf.download(tickers, start='2020-01-01', end='2024-12-31')

# 提取调整收盘价
adj_close = data['Adj Close']
print(adj_close.head())

你看,一行代码就把7只龙头股的数据全拿下来了。yfinance会自动处理多列索引,返回一个MultiIndex的DataFrame。我个人觉得这个设计很巧妙——既保留了数据结构,又方便后续按股票切片。

小技巧: 如果你只想拿某只股票的最近100个交易日数据,可以这样写:yf.download('AAPL', period='100d')。用period参数比用start/end更省事。

4.4 初筛指标计算:从原始数据到决策依据

数据拿到了,接下来就是算指标。我一般把初筛指标分成三类:

指标类别 具体指标 计算逻辑
动量类 20日收益率、60日收益率 (当前收盘价 - N日前收盘价) / N日前收盘价
波动类 20日年化波动率 std(日收益率) * sqrt(252)
流动性类 20日平均成交量 rolling(20).mean()

为什么要选这些指标?你想想看,龙头股首先得“涨得动”(动量),其次不能“上蹿下跳”(波动适中),最后还得“有人玩”(流动性好)。这三个维度缺一不可。

下面我写一个完整的计算函数。这个函数我在项目中反复用过,算是比较成熟的模板。

def calculate_indicators(df, window=20):
    """
    计算初筛指标
    df: 调整收盘价的DataFrame,列名为股票代码
    window: 计算窗口,默认20个交易日
    """
    # 计算收益率
    returns = df.pct_change()
    
    # 动量指标:N日收益率
    momentum = df.pct_change(periods=window)
    
    # 波动率指标:N日年化波动率
    volatility = returns.rolling(window=window).std() * (252 ** 0.5)
    
    # 流动性指标:N日平均成交量(需要原始成交量数据)
    # 这里假设你已经有volume数据
    # avg_volume = volume.rolling(window=window).mean()
    
    # 整合结果
    result = pd.DataFrame({
        'momentum': momentum.iloc[-1],
        'volatility': volatility.iloc[-1],
        # 'avg_volume': avg_volume.iloc[-1]
    })
    
    return result

# 使用示例
indicators = calculate_indicators(adj_close)
print(indicators.sort_values('momentum', ascending=False))

跑完这段代码,你会得到一个表格,里面每只股票都有动量值和波动率值。这时候你就可以开始做初步筛选了——比如只保留动量排名前20%、波动率低于30%的股票。

避坑指南: 我曾经犯过一个错误——直接用原始价格计算动量,忽略了股票拆股和分红的影响。后来发现yfinance的Adj Close已经做了调整,这才放心。所以记住:永远用Adj Close,不要用Close

4.5 知识体系总览

为了让你对整个流程有个直观印象,我画了一张图。这张图把数据获取、指标计算、筛选逻辑串在了一起。

量化初筛模型流程图 数据获取 yfinance.download() 数据清洗 处理缺失值、异常值 指标计算 动量、波动率、流动性 筛选逻辑 动量排名前20% 波动率 < 30% 结果输出 候选股票列表 回测验证 验证筛选策略的有效性 迭代优化

4.6 实战中的坑与对策

代码写完了,图也画了,但实战中总会遇到各种幺蛾子。我把自己踩过的坑列出来,你遇到了直接抄答案就行。

  1. 数据缺失: 有些股票可能在某段时间停牌,导致数据为空。我的处理方式是:如果缺失值超过20%,直接剔除这只股票;如果只是零星缺失,用前向填充法(ffill)。
  2. 股票代码变更: 比如FB改成了META。yfinance会自动处理,但如果你用的是旧代码,可能会拿到空数据。建议定期更新股票池。
  3. 计算速度: 如果你要处理几百只股票,用纯pandas循环会非常慢。我的优化方案是:用numpy向量化计算,或者用numba加速。不过对于初筛阶段,几十只股票完全够用。
我的习惯: 每次跑完代码,我都会把结果存成CSV文件。这样下次可以直接读取,不用重新下载数据。毕竟Yahoo Finance的接口也不是无限次调用的。

4.7 小结

这一章我们干了三件事:用yfinance拿数据、算动量波动率这些初筛指标、把整个流程串成自动化脚本。你可能会觉得这些指标太简单——没错,初筛阶段就是要简单粗暴。复杂的模型留到后面几章再上。

最后提醒一句:代码跑通了只是第一步。真正有价值的是你如何解读这些指标、如何设定筛选阈值。这些经验性的东西,光看书学不来,得自己动手试错。

好了,这一章就到这里。代码拿去跑,有问题随时调试。记住:数据不会骗人,但解读数据的人会


专注资料整理