
你是否曾经追过一个看似强势的行情,最后才发现——整个指数的上涨其实只靠两三只股票在撑?这就是所谓的"窄幅上涨",它脆弱且危险。
2021 年发表在 Economic Modelling 上的一篇论文,研究了 64 个国家从 1973 年到 2018 年的市场数据,发现**市场广度(Market Breadth)**是未来股票收益的稳健预测因子。简单来说,市场广度衡量的是"有多少只股票在真正参与上涨"。
今天我们就来拆解这个概念,并用 Python 实现一个简单的市场广度过滤器,帮助你在实际交易中做出更理性的判断。
市场广度的核心问题是:这波行情是真的吗?
论文将市场广度定义为:一个投资组合中,上涨股票数量与下跌股票数量的差值。
举个形象的例子:想象你的投资组合是一部电梯。价格是电梯显示屏上的楼层数,而广度则代表电梯里到底站满了人,还是只有一个拎着大包小包的人在猛按按钮。
当广度强劲时,上涨的股票多于下跌的股票。这虽然不能保证你一定赚钱,但这种动量更加"分散受力",也更加稳健。
论文的关键发现包括:
在实际交易中,一个看似有效的信号可能被交易成本完全吃掉。来看一个简单的算术:
假设一个基于广度的国家轮动策略,每月毛收益为 +0.30%(约年化 +3.6%)。每次调仓的摩擦成本(价差 + 滑点 + 佣金)为买入 0.10% + 卖出 0.10% = 0.20%。
按月调仓:
净收益 = 0.30% − 0.20% = 0.10%/月,仍然为正。
按周调仓(每月约 4 次):
月成本 = 0.20% × 4 = 0.80%
净收益 = 0.30% − 0.80% = −0.50%/月,直接亏损!
论文也明确指出:频繁调仓会导致交易成本侵蚀策略的盈利能力。所以,先算账,再交易。
下面是一个用 Python 实现的市场广度计算函数,代码简洁且实用:
import pandas as pd
import numpy as np
def calculate_breadth(close_prices: pd.DataFrame) -> pd.DataFrame:
"""
计算市场广度指标。
参数:
close_prices: DataFrame,每列为一只股票的收盘价,索引为日期。
返回:
包含广度指标的 DataFrame。
"""
# 计算每日收益率
ret = close_prices.pct_change().fillna(0)
# 统计上涨和下跌的股票数量
up = (ret > 0).sum(axis=1) # 当日上涨的股票数
down = (ret < 0).sum(axis=1) # 当日下跌的股票数
total = close_prices.shape[1] # 股票总数
# 计算广度指标
breadth = up - down # 原始广度值
breadth_pct = 100.0 * (breadth / total) # 广度百分比
return pd.DataFrame({
'up': up, # 上涨数量
'down': down, # 下跌数量
'breadth': breadth, # 广度值
'breadth_pct': breadth_pct # 广度百分比
})论文的理论很扎实,但最好的学习方式是亲手实验。下面是一个你可以在一周内完成的实战方案。
第 1 步:选择一个股票池
可以是某个指数的成分股、一组国家 ETF,或者你自己的 30–60 只股票观察清单。
第 2 步:定义广度指标
使用最简单的公式:
每日广度 = 当日上涨股票数 − 当日下跌股票数
如果需要标准化:
广度百分比 = ((上涨数 − 下跌数) / 总数) × 100
第 3 步:每天记录一次
每天收盘后记录:总股票数、上涨数、下跌数、广度值、当日指数收益率。
第 4 步:制定下周决策规则
在第 5 天,根据 5 天累计广度做出一个决策:
下面是完整的 Python 示例代码:
import pandas as pd
import numpy as np
def calculate_breadth(close_prices: pd.DataFrame) -> pd.DataFrame:
"""计算市场广度指标"""
ret = close_prices.pct_change().fillna(0)
up = (ret > 0).sum(axis=1)
down = (ret < 0).sum(axis=1)
total = close_prices.shape[1]
breadth = up - down
breadth_pct = 100.0 * (breadth / total)
return pd.DataFrame({
'up': up,
'down': down,
'breadth': breadth,
'breadth_pct': breadth_pct
})
def breadth_filter(breadth_df: pd.DataFrame, window: int = 5) -> pd.Series:
"""
基于滚动窗口的广度过滤器。
参数:
breadth_df: calculate_breadth() 的返回结果。
window: 滚动窗口天数,默认为 5 天。
返回:
布尔型 Series,True 表示允许做多,False 表示应规避风险。
"""
# 计算滚动 N 天的累计广度
rolling_breadth = breadth_df['breadth'].rolling(window=window).sum()
# 累计广度为正时,允许做多;否则规避风险
allow_long = rolling_breadth > 0
return allow_long
# ===== 模拟数据示例 =====
np.random.seed(42)
# 模拟 10 只股票、20 个交易日的收盘价数据
dates = pd.bdate_range(start='2026-02-01', periods=20) # 生成工作日日期
stocks = [f'股票_{i+1}' for i in range(10)] # 10 只股票
# 以 100 为基准价格,叠加随机涨跌生成模拟价格
price_data = 100 + np.cumsum(np.random.randn(20, 10) * 0.5, axis=0)
close_prices = pd.DataFrame(price_data, index=dates, columns=stocks)
# 计算广度
breadth_df = calculate_breadth(close_prices)
# 应用 5 天广度过滤器
signal = breadth_filter(breadth_df, window=5)
# 合并结果并展示
result = breadth_df.copy()
result['累计广度信号'] = signal.map({True: '许做多', False: '规避风险'})
print("===== 市场广度分析结果 =====\n")
print(result.to_string())
print("\n===== 最新交易信号 =====")
print(f"最新日期:{result.index[-1].strftime('%Y-%m-%d')}")
print(f"当日广度:{result['breadth'].iloc[-1]}")
print(f"交易建议:{result['累计广度信号'].iloc[-1]}")运行结果类似如下:
===== 市场广度分析结果 =====
up down breadth breadth_pct 累计广度信号
2026-02-02 0 0 0 0.0 NaN
2026-02-03 5 5 0 0.0 NaN
2026-02-04 6 4 2 20.0 NaN
2026-02-05 4 6 -2 -20.0 NaN
2026-02-06 5 5 0 0.0 ✅ 允许做多
...
===== 最新交易信号 =====
最新日期:2026-02-27
当日广度:2
交易建议:✅ 允许做多注意:以上为模拟数据,实际结果因随机种子和真实数据而异。
广度过滤器虽然简单有效,但也有其局限性。
首先,广度不是预测机器,而是参与度计量器。它告诉你当前行情有多少股票在参与,而不是行情未来会怎么走。
其次,广度可能滞后。市场可能已经开始反转,但广度信号还停留在上一个状态。它也可能在你失去耐心之前一直保持低迷。
第三,任何基于广度的策略都受交易成本制约。正如前面的算术所示,频繁调仓会把正收益变成负收益。做交易之前先做算术。
最后,记住一点:仓位要小到足以让犯错成为学费,而不是灾难。
市场广度是一个被学术研究证实、且在实战中极具价值的工具。它回答了一个核心问题——这波行情到底有多少股票在真正参与?
对于 Python 学习者来说,实现一个广度过滤器是一个很好的练手项目:它涉及 pandas 数据处理、滚动窗口计算、布尔索引等常用技能,同时又能直接应用于真实的交易场景。
核心要点回顾:
2026年全面升级已落地!【数据科学实战】知识星球核心权益如下:
星球已沉淀丰富内容生态——涵盖量化文章专题教程库、因子日更系列、高频数据集、PyBroker实战课程、专家深度分享与实时答疑服务。无论您是初探量化的学习者,还是深耕领域的从业者,这里都是助您少走弯路、高效成长的理想平台。诚邀加入,共探数据驱动的投资未来!
好文推荐
1. 用 Python 打造股票预测系统:Transformer 模型教程(一)
2. 用 Python 打造股票预测系统:Transformer 模型教程(二)
3. 用 Python 打造股票预测系统:Transformer 模型教程(三)
4. 用 Python 打造股票预测系统:Transformer 模型教程(完结)
6. YOLO 也能预测股市涨跌?计算机视觉在股票市场预测中的应用
9. Python 量化投资利器:Ridge、Lasso 和 Elastic Net 回归详解
好书推荐