周内效应再检验:星期几真的有超额收益吗
『周一必跌、周五必涨』是散户最爱的都市传说之一。本文用 20 年日频合成指数(含 GARCH 波动聚集与周内漂移衰减),严格复现 Cross(1973)/French(1980) 式的周内效应:周一 −3.7bp(t=−1.89)、周五 +5.6bp(t=+2.81),跳过周一把买入持有的 Sharpe 从 0.20 拉到 0.42,但后半段该效应已衰减过半——这恰好解释了为什么教科书说它存在、而你实盘却抓不到。附完整 Python 与六类真实陷阱(高阶)。
「周一绿、周五红」几乎是每个炒过股的人都听过的经验法则。它有没有统计基础?有。1973 年 Cross 发现道指周五收益显著高于周一,1980 年 French 用 1953–1977 年数据确认了同样的模式,后来的研究把它推广到全球几十个市场。但问题是:这个效应在 1990 年代之后普遍衰减甚至消失。本文不重复教科书结论,而是用一份自洽的合成数据,把周内效应「长什么样、怎么检验、能不能交易、为什么会失效」一次性讲清楚。
结论先放这:在含周内漂移的合成指数上,周一确实显著为负(−3.7bp/日,t=−1.89)、周五显著为正(+5.6bp/日,t=+2.81);「跳过周一、其余交易日等权持有」把 Sharpe 从 0.20 提升到 0.42、最大回撤从 −36% 收窄到 −33%。但把样本切成两半,会发现后半段周一的负收益只剩前半段的 16%、周五也只有 29%——效应在衰减,这正是实盘抓不住它的根本原因。 附完整 Python 与六类真实陷阱(高阶)。

一、什么是周内效应,为什么它可能成立#
周内效应(day-of-the-week effect)指股票收益在星期几之间存在系统性、可重复的均值差异。学术上的经典配置是:
- 周一效应(Monday effect):周一平均收益显著为负,甚至是全周唯一为负的日子。
- 周五效应(Friday effect):周五平均收益显著为正,往往是一周里最高的一天。
行为金融给过几个说得通的解释:
- 结算周期滞后:过去美股 T+5 交割时代,周一结算的是上周四、周五的买单,卖压集中释放,压低周一开盘。
- 周末情绪积累:坏消息在周末发酵,投资者周一开盘集中抛售(负面信息在周一反应)。
- 做市商持隔夜敞口的成本:周末两天无法对冲,周一开盘前做市商要求更高补偿。
注意:这些解释几乎都指向「制度性摩擦」,而制度一旦改了(交割缩短、算法交易、24 小时信息流),效应就会衰减。后面我们用数据验证这一点。
二、合成数据:一份诚实的实验台#
为了在没有幸存者偏差、没有未来函数、可复现的前提下讲清机制,我们用一份合成日频指数,显式嵌入两个真实市场的特征:
- GARCH(1,1) 波动聚集:大波动后紧跟大波动,用
σ_t² = ω + α·ε_{t-1}² + β·σ_{t-1}²。 - 周内漂移 + 随时间衰减:前半段周一 −5.5bp、周五 +4.5bp,后半段整体衰减到 45%。
- 轻度 AR(1) 自相关,模拟微观结构噪声。
import numpy as np
import pandas as pd
rng = np.random.default_rng(20260716)
dates = pd.bdate_range("2005-01-03", "2025-12-31")
n = len(dates)
wd = dates.weekday.to_numpy() # 0=周一 .. 4=周五
# 周内漂移:周一弱、周五强;后半段整体衰减
base = 0.00020
full = np.array([-0.00055, 0.00000, 0.00005, 0.00020, 0.00045]) # 周一..周五
decay = np.where(np.arange(n) < n // 2, 1.0, 0.45)
eff = full[wd] * decay
# GARCH(1,1) 波动聚集
omega, a, b = 1.0e-6, 0.08, 0.90
sig = np.zeros(n); sig[0] = 0.010
eps = np.zeros(n)
z = rng.standard_normal(n)
for i in range(1, n):
sig[i] = np.sqrt(omega + a * eps[i-1]**2 + b * sig[i-1]**2)
eps[i] = z[i] * sig[i]
r = base + eff + eps
for i in range(1, n): # 轻度 AR(1) 微观结构噪声
r[i] = 0.05 * r[i-1] + (1 - 0.05) * r[i]
r = pd.Series(r, index=dates)python这段数据的关键点:漂移是写进生成过程的,所以我们知道「真相」;检验的目的不是「证明效应存在」(它当然存在),而是演示怎么正确地度量它、以及它会怎么骗你。
三、怎么检验:均值 + t 统计#
最直接的检验是「每个星期几的平均收益是不是显著不等于 0」。注意要用 t 统计而不是只看均值大小——因为日频噪声极大,一个 ±3bp 的均值需要上千个样本才能显著。
names = ["周一", "周二", "周三", "周四", "周五"]
for d in range(5):
x = r[wd == d].to_numpy()
m = x.mean(); s = x.std(ddof=1)
t = m / (s / np.sqrt(len(x)))
print(f"{names[d]}: 均值={m*10000:+.2f}bp t={t:+.2f} n={len(x)}")python跑出来的结果(基于这份合成数据):
周一: 均值=-3.71bp t=-1.89 n=1096
周二: 均值=+0.59bp t=+0.30 n=1096
周三: 均值=-0.58bp t=-0.29 n=1096
周四: 均值=+2.05bp t=+1.06 n=1095
周五: 均值=+5.63bp t=+2.81 n=1095plaintext周一在 10% 水平显著为负(t=−1.89)、周五在 1% 水平显著为正(t=+2.81)。但注意:周二、周三、周四都不显著——日内效应并不是「均匀的梯度」,而是集中在「周一最差、周五最好」两端,中间几天其实没有稳定超额。这正是真实文献里的典型形态。

四、能不能交易:「跳过周一」策略#
最直接的交易化思路:周一空仓(或持现金等价物),其余四天等权持有指数。我们用合成数据对比「买入持有」与「跳过周一」:
def metrics(ret):
cum = np.exp(np.log1p(ret).cumsum())
ann = cum[-1] ** (252 / len(ret)) - 1
sharpe = ret.mean() / ret.std(ddof=1) * np.sqrt(252)
peak = np.maximum.accumulate(cum); dd = (cum - peak) / peak
return ann, sharpe, dd.min()
bh_ann, bh_sh, bh_mdd = metrics(r.to_numpy())
skip_ret = r.to_numpy().copy(); skip_ret[wd == 0] = 0.0
sk_ann, sk_sh, sk_mdd = metrics(skip_ret)
print(f"买入持有: 年化={bh_ann:.3f} Sharpe={bh_sh:.2f} 回撤={bh_mdd:.2%}")
print(f"跳过周一: 年化={sk_ann:.3f} Sharpe={sk_sh:.2f} 回撤={sk_mdd:.2%}")python结果:买入持有 Sharpe 0.20、最大回撤 −36%;跳过周一 Sharpe 0.42、回撤 −33%。跳过最差的一天,把样本里最大的一块负均值剔除,Sharpe 翻倍、回撤收窄——逻辑上完全自洽。
五、最关键的检验:效应会衰减吗#
教科书说效应「曾经存在、现在消失」。我们直接把样本切成两半验证:
split = dates[n // 2]
for d in range(5):
sub = r[wd == d]
m1 = sub[dates[wd == d] < split].mean()
m2 = sub[dates[wd == d] >= split].mean()
print(f"{names[d]}: 前半段={m1*10000:+.2f}bp 后半段={m2*10000:+.2f}bp")python周一: 前半段=-6.4bp 后半段=-1.0bp
周二: 前半段=+1.3bp 后半段=-0.1bp
周三: 前半段=-0.9bp 后半段=-0.2bp
周四: 前半段=+4.6bp 后半段=-0.5bp
周五: 前半段=+8.7bp 后半段=+2.5bpplaintext后半段所有星期几的信号都衰减到前半段的 16%~29%。 这意味着:即便你 2005 年发现了「跳过周一」,到 2015 年之后这个 alpha 也基本被市场吃掉了。这是周内效应最真实的面貌——它不是一个可以躺赚的印钞机,而是一个会随时间被套利掉的制度性残差。

六、六类真实陷阱(高阶)#
做日历异象研究,以下坑一个比一个阴:
- 多重比较偏差(multiple testing):你看了周一到周五 5 天,等于做了 5 次检验,至少要 Bonferroni 校正(阈值从 0.05 降到 0.01)。不校正时「周五显著」很可能只是 5 次里碰巧命中的一次。
- 幸存者偏差:用现在还活着的指数成分股回测,等于自动排除了「周一大跌然后退市」的公司,会系统性高估正效应。
- 非交易日与节假日污染:很多「周一负收益」其实是周日/周一的隔夜跳空(周末利空),不是周一当天的交易行为;用开盘价而非收盘价定义收益会改变结论。
- 幸存者择时:如果你「发现」周一效应后再交易,前半段赚、后半段亏,样本内/样本外表现会严重背离。
- 交易成本:跳过周一意味着每周买卖一次,频繁换手的成本会吞掉大部分薄 alpha(本合成数据没建模成本,实盘必须扣)。
- 全球不同步:A 股、美股、港股的结算制度和交易习惯不同,周一效应方向可能相反;跨市场结论不能直接平移。
七、结论:它存在,但别指望靠它吃饭#
周内效应在统计上是真实存在的——周一系统性偏弱、周五偏强,跳过最差的那天能显著改善风险调整收益。但它有三个致命现实特征:① 信号极薄(每天几个 bp),② 集中在周一/周五两端、中间几天无超额,③ 随时间被套利衰减。
所以它在研究框架里的正确位置是:作为「过滤条件」而非「盈利策略」——比如你本来要做动量,可以默认避开周一开盘降低噪声;而不是单独拿它当印钞机。真正的 alpha 永远在「薄、衰减、难套利」三者之间权衡,周内效应恰恰演示了「前两个」为什么让一个看似成立的策略实盘扑空。
本文数据由自洽合成生成(含 GARCH 波动聚集与周内漂移衰减),用于机制演示,非真实行情,不构成投资建议。所有 t 统计均基于日频收益的样本标准差计算。