← 返回目录
p6.5动手⏱ 约 16 分钟

网格策略审判:赢在哪一步

同一条网格,区间用全样本极值定 vs 用过去 250 日定——年化差 1.80 / 3.16 / 3.64 个百分点

🔎 最后验证 2026-07📚 来源:三个标的 × 三种区间口径 × 三档成本的网格回测,2026-07-31 于 ECS 实测,输出见 code/outputs/stdout.txt🧰 qlab.engine(本课自研)、pandas 3.0.5、Python 3.12.13
为什么学这个

网格策略号称"赚波动的钱""远超定投"。

这一节把它放进 P4 那台带约束的引擎里跑,只改一个地方:网格区间的上下界怎么来。

                        事后区间     事前区间     差
                     (全样本极值) (过去250日)
沪深300 指数              3.24%       1.44%    +1.80 pp
sh.600000               5.02%       1.87%    +3.16 pp
sh.600019               5.68%       2.04%    +3.64 pp

同一条策略、同一份数据、同一套成本。唯一的改动是:区间是拿全样本的最高最低价定的,还是拿过去 250 日定的。

前者的意思是——你在 2010 年就知道了 2026 年的最低点。

很多"网格远超定投"的回测,赢在这一步,而不是赢在策略。

💡 打个比方

有人告诉你他射箭百发百中。

你去看,发现他是先射,再在箭落的地方画靶心

网格的"区间上下界",就是那个靶心。先看完全部行情再定区间,和先画靶心再射箭,是同一件事。

一、先说清网格是什么

网格没有任何预测成分。它是一个逆势的仓位函数:价格越低,仓位越高。

把"跌一格买一格、涨一格卖一格"写成仓位形式,是同一件事的两种写法:

def make_grid(lo, hi, n=10):
    """价格 ≤ lo → 满仓;≥ hi → 空仓;中间按 n 档阶梯。"""
    def f(h):
        p = float(h["close"].iloc[-1])
        x = (hi - p) / (hi - lo)
        return float(np.clip(np.floor(np.clip(x, 0, 1) * n) / n, 0.0, 1.0))
    return f

这个写法让本节的问题变得很清楚:lohi 从哪来?

网格的收益来源只有一个:标的在区间内来回震荡。它不预测方向,也不假装预测。

问题从来不在"网格有没有用",而在"区间是谁定的、什么时候定的"。

二、用全样本极值定区间(几乎人人都在犯的未来函数)

标的策略年化%最大回撤%夏普成交笔数
沪深300网格(事后区间)3.24-31.40.32010
买入持有2.07-46.50.2032
定投(仓位版)3.03-40.80.2683
sh.600000网格(事后区间)5.02-38.00.383668
买入持有4.32-44.80.2931
定投(仓位版)5.74-41.10.368290
sh.600019网格(事后区间)5.68-45.70.3772727
买入持有1.92-56.30.2211
定投(仓位版)5.31-54.20.322934

看起来网格确实赢了——三个标的里两个跑赢买入持有,回撤也更小。

注意 sh.600000 那一组:即使用了事后区间,网格(5.02%)仍然输给定投(5.74%)。

也就是说,"远超定投"这个说法,在开了未来函数的条件下都不总是成立

三、只改一个地方:区间换成"只用过去 250 日"

标的区间口径年化%最大回撤%夏普成交笔数
沪深300事后(全样本极值)3.24-31.40.32010
事前(过去 250 日)1.44-25.80.18246
事前 ±20% 缓冲1.62-27.70.20911
→ 事后减事前+1.80 pp
sh.600000事后5.02-38.00.383668
事前1.87-25.90.2211179
事前 ±20% 缓冲3.08-21.70.331871
→ 事后减事前+3.16 pp
sh.600019事后5.68-45.70.3772727
事前2.04-33.40.2052256
事前 ±20% 缓冲3.04-31.10.2672766
→ 事后减事前+3.64 pp
⚠️ 避坑

这 1.80 ~ 3.64 个百分点,不是策略赚的,是"提前知道结果"赚的。

换成事前区间之后:

  • 沪深300:网格 1.44% vs 买入持有 2.07%输了
  • sh.600000:网格 1.87% vs 买入持有 4.32%大幅输了
  • sh.600019:网格 2.04% vs 买入持有 1.92% → 险胜

三个标的里,只剩一个还能勉强跑赢买入持有,而且优势只有 0.12 个百分点。

有一个地方要如实说:事前网格的最大回撤确实更小(-25.8% / -25.9% / -33.4%,对比买入持有的 -46.5% / -44.8% / -56.3%)。

这是真的,而且是网格唯一站得住的优点——它和 p6.4 的定投一样,是一个降低波动、降低回撤的仓位方案,不是一个提高收益的策略。

但"降低回撤"和"远超定投"是两个完全不同的宣传语。

🔧 动手做:网格"远超定投",藏了一个未来函数(6 分钟)

网格策略常被吹"远超定投"。跑 python grid_trial.py——它先用全样本极值定网格区间(几乎人人都这么画),再只改一处:区间换成只用过去 250 日

你会看到(实测):同一条网格,区间从"事后全样本极值"换成"事前过去 250 日",年化直接掉 1.80 / 3.16 / 3.64 个百分点

想明白:那个"远超"的漂亮回测,是用了你当时根本不知道的未来最高最低价布网格——典型的未来函数。改成只用历史,优势大半蒸发。任何"网格神话",先问:网格区间怎么定的?用没用到未来价格?

四、成本敏感性:高换手策略绕不开的一关

按 p5.7 的纪律,任何高换手结论都要过成本这一关(事前区间口径):

标的零成本默认 2.5bp+5bp翻倍 5bp+10bp零→翻倍
沪深3001.201.441.13-0.07
sh.6000002.591.871.32-1.27
sh.6000192.872.041.45-1.42

两只个股上,成本从零到翻倍吃掉 1.3~1.4 个百分点——而它们的成交笔数是 1179 和 2256 笔。

⚠️ 避坑

沪深300 那一行不是单调的:零成本 1.20%,默认成本反而 1.44%。

这不是算错,是路径依赖:成本改变权益 → 改变每次调仓的股数取整、以及"差额是否超过一手"的判定 → 成交路径分叉。在成交笔数很少(10~46 笔)时,这种分叉足以盖过成本本身的量级。

这也是为什么 p4.10 的单元测试里"成本单调"那一条,测的是固定策略下的同一条路径,而不是"任何策略在任何标的上都单调"。

一个在低换手样本上非单调的成本响应,不是 bug,是提醒你样本量不够。

五、判断一份网格回测是否可信,只问一句

区间上下界是哪一天定的?

如果答案里出现了回测结束之后才知道的信息——全样本最高价、最低价、历史极值分位——后面所有数字都不用看了

这是 p1.2「未来函数」在网格上的具体形态,而且比均线类策略更隐蔽:

未来函数藏在哪
均线策略信号本身(用了今日收盘算今日信号)
网格策略不在信号里,在参数里——区间是拿全样本定的

信号层面完全干净、每一步都只用历史数据,但参数是从未来借来的。

同类问题在本课出现过两次:p5.4 的"样本内最优参数"、p5.1 的"从 16 种读法里挑最好的"。

它们的共同点是:错误不在计算,在「这个数字是什么时候知道的」。

六、那网格到底能不能用

能用,但要把它当成它本来的样子:

它是它不是
一个逆势的仓位规则一个预测工具
一个降低回撤的方案(实测 -25.8% vs -46.5%)一个提高收益的策略
依赖标的在区间内震荡的方案在单边行情里也有效的方案

单边下跌时它会不断买入并被套满;单边上涨时它会过早卖光。这两个失效条件不是缺陷,是它的定义带来的必然结果。

❓ 测验
一份网格回测报告写:「回测区间 2015–2025,网格上下界设为 3000 和 5500 点,年化 12%」。你最该追问什么?
✏️ 填空
网格策略的未来函数通常不在信号里,而在 ___ 里——区间上下界是拿全样本极值定的。

📌 免责:本课为技术教学,网格与定投均为演示口径,标的按代码取样(非精选),不推荐任何策略或标的;历史模拟不构成投资建议。

✅ 小结

四件事:

  1. 网格没有预测成分,它是一个逆势的仓位函数:价格越低仓位越高。收益来源只有一个——标的在区间内来回震荡
  2. 未来函数藏在参数里,不在信号里。同一条策略,区间从"全样本极值"换成"过去 250 日",年化差 1.80 / 3.16 / 3.64 pp;换成事前区间后,三个标的里只剩一个还能勉强跑赢买入持有(2.04% vs 1.92%,优势 0.12 pp)
  3. 但要如实说:事前网格的回撤确实更小(-25.8% / -25.9% / -33.4% vs 买入持有 -46.5% / -44.8% / -56.3%)。这是它唯一站得住的优点——它和定投一样是降低回撤的仓位方案,不是提高收益的策略
  4. 成本敏感性必须报:两只个股上零成本到翻倍吃掉 1.27 / 1.42 pp;而沪深300 那一行非单调,原因是成交笔数太少(10~46 笔)时路径分叉盖过了成本量级——非单调不是 bug,是提醒你样本量不够

一句可以直接用的追问:区间上下界是哪一天定的? 如果答案里出现了回测结束之后才知道的信息,后面所有数字都不用看了。

下一节检验另一个更精致的版本:"智能定投"——用估值或均线决定每期投多少。它比普通定投多了参数,而多参数意味着多一层过拟合风险(p5.4/p5.5)。

下一节 → 智能定投的诚实检验
🔎 来源与核验· 4 条,点开核对
本节每个关键论断都对应一个可追溯的来源 —— 这是本课程"靠谱、不过时"的底线。
「事后区间(全样本极值)网格:沪深300 年化 3.24%/回撤 -31.4%/10 笔;sh.600000 5.02%/-38.0%/668 笔;sh.600019 5.68%/-45.7%/2727 笔。同期买入持有 2.07%/4.32%/1.92%,定投(仓位版)3.03%/5.74%/5.31%」
📚 本节 code/grid_trial.py,2026-07-31 于 ECS 实测,输出见 code/outputs/stdout.txt✓ 已核验 2026-07
「事前区间(过去 250 日极值)网格:沪深300 1.44%/-25.8%;sh.600000 1.87%/-25.9%;sh.600019 2.04%/-33.4%。事后减事前分别为 +1.80 / +3.16 / +3.64 pp」
📚 同上实测✓ 已核验 2026-07
「事前区间 ±20% 缓冲:沪深300 1.62%/-27.7%;sh.600000 3.08%/-21.7%;sh.600019 3.04%/-31.1%」
📚 同上实测✓ 已核验 2026-07
「成本敏感性(事前区间):零成本/默认/翻倍 年化 —— 沪深300 1.20/1.44/1.13%;sh.600000 2.59/1.87/1.32%;sh.600019 2.87/2.04/1.45%」
📚 同上实测✓ 已核验 2026-07
网格以「价格越低仓位越高」的阶梯仓位函数实现(10 档),与挂单撮合形式在忽略排队细节时等价;定投为仓位版近似(60 个月建满仓),与 p6.4 的现金流口径不同,仅用于同一引擎下的形状对比。沪深300 的成本响应非单调,系成交笔数过少导致的路径分叉。
智图软件的赞赏码
都看到这了,打个赏呗!
接下来 · p6.6
智能定投的诚实检验:IRR 全赢,终值全输
继续读下一节 →