Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor ·

网格交易机器人 真实评测

网格交易机器人通过固定区间低买高卖获利。本文用真实美股数据拆解其机制,揭示哪种市场形态能赚钱、哪种会导致亏损,并提供可复现的图表分析。

网格交易机器人会在固定价格间隔上挂出一系列订单:在当前价格下方的每个档位挂买入单,在上方的每个档位挂卖出单。每当市场下跌一档,机器人就买入。每当市场回升一档,机器人就卖出之前低价买入的头寸。这种机制从价格震荡中获利,而当市场单方向持续远离网格时,它就会积累一个未平仓头寸。

本页面拆解了这种机制,然后衡量决定其结果的两种市场形态。下方的每个图表都是基于真实美股价格运行的存储查询,并固定在特定日期,以确保数据可复现。

网格交易机器人如何运作

三个参数定义一个网格:区间的上限和下限、区间内的网格线数量,以及每条网格线的订单规模。网格线之间的间距由前两个参数决定。

以下是计算过程,为了清晰起见,使用了从任何真实报价中选取的整数。假设一只股票交易价格接近100美元,操作者设置了一个从95美元到105美元的网格,有11条线,每条线间隔1美元,每条线挂100股。价格跌至99美元,挂单的买入指令成交。价格回到100美元,对应的卖出指令成交,完成一次配对,毛利润为100美元。两个订单都重新挂出。在这一小时内,公司基本面没有任何变化。该头寸只是在两个相邻档位之间完成了一次往返。

在公开流传的开源项目中,有两种变体。算术网格按固定美元金额设置线间距。几何网格按固定百分比设置线间距,这使得在较大范围内,每次往返的百分比利润保持稳定。文档还将中性网格(从空仓开始,双向操作)与多头网格(初始持有库存,在上涨时卖出)区分开来。

其收益形态可以用一句简单的话概括。一次完成的往返交易,其利润上限为一个网格步长减去成本。当价格离开区间时积累起来的未平仓头寸,则没有相应的上限。

网格所需的市场形态

网格靠价格“行走”来获利,而非靠方向。两只股票在经历截然不同的路径后,可能在期末收于同一价格。将每日价格波动的绝对值相加,就得到了总行走距离。用净变动除以该距离,就得到了效率比,这是衡量路径方向性程度的标准指标。低比率描述了一条蜿蜒曲折的路径。高比率描述了一条直线前进的路径。

查询行程距离 vs 净变动:12只常见股票,2024年1月至2026年6月
每个数字背后的完整 SQL
WITH daily AS (
    SELECT ticker,
           toDate(toTimeZone(window_start, 'America/New_York')) AS dt,
           argMax(toFloat64(close), toTimeZone(window_start, 'America/New_York')) AS c
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('SPY','KO','PG','JNJ','VZ','MO','XOM','JPM','WMT','NVDA','TSLA','NFLX')
      AND toDate(toTimeZone(window_start, 'America/New_York')) BETWEEN toDate('2024-01-02') AND toDate('2026-06-30')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY ticker, dt
),
steps AS (
    SELECT ticker, dt, c,
           c / lagInFrame(c) OVER (PARTITION BY ticker ORDER BY dt) - 1 AS ret
    FROM daily
)
SELECT ticker,
       round(sum(abs(ret)) * 100, 0) AS travel_pct,
       round(abs(argMax(c, dt) / argMin(c, dt) - 1) * 100, 1) AS net_move_pct,
       round(100 * abs(argMax(c, dt) / argMin(c, dt) - 1) / sum(abs(ret)), 1) AS efficiency_pct
FROM steps
WHERE ret > -0.5 AND ret < 0.5
GROUP BY ticker
ORDER BY efficiency_pct
Run this yourself

请一起阅读第一行和最后一行。PG 覆盖了 527% 的累计日波动,最终收盘价与起始点相差 0.9%,效率比为 0.2%。SPY 则处于另一端,为 14.3%,将 415% 的行走距离转化为 59.2% 的净变动。放置在第一条路径上的网格梯子会反复触及自己的各个档位。而放置在第二条路径上的同一个梯子则会被市场抛在后面。

平静和区间震荡是相关但不同的属性。一只股票可能以非常小的日涨幅向上漂移,但仍然会让网格陷入困境,这也是为什么在低波动率异象文献中研究的股票,并非自动成为网格交易标的的原因之一。

计算往返次数

效率比是一个视角。网格收入取决于更具体的东西:价格实际重新触及某个水平的次数。以每个日历年的首个收盘价为锚点,统计收盘价落在该锚点另一侧的交易日数量,就得到了一条网格线本应捕捉到的穿越次数。这里以可口可乐(KO)为例,这是一个大型、流动性强的消费类股票,网格交易文档通常倾向于介绍这类股票。

查询KO:年内开盘价穿越次数,按日历年,2019至2025
每个数字背后的完整 SQL
WITH daily AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS dt,
           argMax(toFloat64(close), toTimeZone(window_start, 'America/New_York')) AS c
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'KO'
      AND toDate(toTimeZone(window_start, 'America/New_York')) BETWEEN toDate('2019-01-01') AND toDate('2025-12-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY dt
),
anchored AS (
    SELECT toYear(dt) AS year, dt, c,
           first_value(c) OVER (PARTITION BY toYear(dt) ORDER BY dt) AS anchor
    FROM daily
),
sided AS (
    SELECT year, dt, c, anchor,
           if(c >= anchor, 1, 0) AS side,
           row_number() OVER (PARTITION BY year ORDER BY dt) AS rn,
           lagInFrame(if(c >= anchor, 1, 0)) OVER (PARTITION BY year ORDER BY dt) AS prev_side
    FROM anchored
)
SELECT year,
       countIf(rn > 1 AND side != prev_side) AS crossing_count,
       count() AS sessions,
       round((argMax(c, dt) / any(anchor) - 1) * 100, 1) AS net_change_pct
FROM sided
GROUP BY year
ORDER BY year
Run this yourself

2019 年,收盘价穿越其开盘价水平 8 次,共 252 个交易日,年末收盘价与该水平相差 17.9%。在 2025 年,穿越次数为 6 次,共 250 个交易日,净变动为 13%。一条线,一只股票,网格交易的原材料在不同年份之间会相差数倍,而且无法提前预知下一年的次数。

这种可变性是一个隐蔽的问题。网格的宣称回报率通常按每次完成的往返交易来报价,而往返交易的次数是由市场决定的,而非由设置决定。

网格在何处失效

失效模式具有特定的形态。固定一个网格区间,然后让市场离开它。下图中的天花板和地板是2024年前20个交易日的最高和最低收盘价,在接下来的30个月里保持不变,并绘制了标普500指数追踪基金的月度收盘价。

查询固定于2024年初的网格,及标普500追踪器后续走势
每个数字背后的完整 SQL
WITH daily AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS dt,
           argMax(toFloat64(close), toTimeZone(window_start, 'America/New_York')) AS c
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND toDate(toTimeZone(window_start, 'America/New_York')) BETWEEN toDate('2024-01-02') AND toDate('2026-06-30')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY dt
),
opening_20 AS (
    SELECT c FROM daily ORDER BY dt LIMIT 20
),
band AS (
    SELECT min(c) AS grid_low, max(c) AS grid_high FROM opening_20
),
monthly AS (
    SELECT toStartOfMonth(dt) AS month_start, argMax(c, dt) AS close_px
    FROM daily
    GROUP BY month_start
)
SELECT formatDateTime(monthly.month_start, '%Y-%m') AS month,
       round(monthly.close_px, 2) AS spy_close,
       round(band.grid_high, 2) AS grid_top,
       round(band.grid_low, 2) AS grid_bottom
FROM monthly, band
ORDER BY monthly.month_start
Run this yourself

该区间从 467.27 美元到 491.26 美元。该系列的第一个月收盘价为 482.92 美元,在区间内。在 30 个月中的最后一个月,收盘价为 746.32 美元,远高于天花板,图表显示价格线离开了区间,再也没有回来。

让我们看看网格梯子沿着这条路径会做什么。在区间内上涨时,机器人逐档卖出库存,每次锁定一个步长的利润。在天花板之上,它持有现金并观望。此后每一次上涨,都是操作者不再参与的收益,这是失效的温和版本。

严重的版本是镜像情况。价格跌破地板,机器人在下跌过程中在每个档位都买入了,因此它现在持有整个梯子的库存,平均成本高于市场价格,每一次进一步下跌都会扩大未实现亏损。一个曾经产生稳定、小额、明显成功交易的区间,变成了一个集中的头寸。网格营销将这种情况描述为机器人“卡住了”;在券商对账单上,这是一个没有内置退出机制的未平仓回撤。

成本随交易次数增加而增加

网格完成许多小额交易,每笔交易都要支付一次往返的全部成本:买卖价差,加上适用的佣金或交易所费用。买卖价差是网格计算中最常被忽略的部分,因为它永远不会作为单独项目出现在对账单上。

说明性的计算很快。对于一只100美元的股票,价差为1美分,一次在买卖双方都跨越价差的往返交易,大约会损失2美分,即名义本金的0.02%。相对于1美元的网格步长,这大约是每笔毛利润的2%。将价差扩大到5美分(这是流动性较差的股票的常见数字),同样的往返交易会损失10美分,相对于1美元的毛利润,即10%。将网格收紧到10美分的步长以捕捉更多震荡,会使每笔交易的毛利润降至10美分,而成本保持不变,那么5美分的价差现在会吞噬整个交易。

这种关系为有用的网格间距设定了下限:步长必须相对于往返成本保持较大,网格越紧,其收入中属于交易所而非操作者的部分就越多。

为什么回测会美化网格机器人

网格策略会产生异常吸引人的回测结果,有四个结构性原因可以解释大部分情况。

  1. 事后选择区间。 在看到数据后选择的边界,必然会包含该数据。一个拟合到区间震荡时期的网格,在该时期会显示出很高的命中率。
  2. 未平仓的梯子。 在选定结束日期停止的测试,通常会计算已实现的往返交易,同时慷慨地处理剩余库存。诚实的会计处理会在最后一天按市价计算未平仓头寸,并将该亏损计入结果。
  3. 成交假设。 模拟的挂单在价格触及时会成交。真实的订单队列并非总能在触及价格时成交,而在快速市场中,未能成交的交易中,盈利的交易占比往往不成比例地高。
  4. 参数密度。 边界、线数、间距和订单规模,为单一价格序列提供了四个可调节的旋钮,这足以拟合几乎任何历史窗口。

上述的穿越次数是对这四个因素的反驳。它们仅来自价格历史,不附带任何设置,并且每年都在变化,这是任何参数选择都无法控制的。任何评估网格交易主张的人都可以问它一个简单的问题:这依赖于多少次完成的往返交易,这个次数从何而来?在模拟器上进行一段时间的实践,并在结束时按市价计算未平仓的梯子,比一张已实现交易的图表更能诚实地回答这个问题。

常见问题

网格交易机器人真的能赚钱吗?

网格在每次完成的往返交易中赚取有上限的利润,并在价格离开其区间时承担一个无上限的未平仓头寸。在任何时期内,已实现的往返交易是否超过未平仓头寸,取决于市场在该区间内的震荡程度,这是市场的属性,而非软件的属性。

什么样的市场条件适合网格机器人?

该机制是为价格反复重新触及相同水平的市场而设计的:相对于净变动,总行走距离要高。在上面的12只股票图表中,效率比从震荡端的 0.2% 到趋势端的 14.3% 不等,而网格梯子机制只在第一种情况下才能反复触及自己的档位。

当价格突破网格区间时会发生什么?

在区间之上,机器人已卖光库存,持有现金,而市场继续上涨,它无法参与。在区间之下,它持有在下跌过程中买入的每一个档位,平均成本高于当前价格,每一次进一步下跌都会扩大该未实现亏损。

网格交易与定投有何不同?

两者都会在价格下跌时买入更多,但相似之处仅此而已。定投是按固定时间表投入固定金额,没有退出规则,也没有上限。网格交易则是在预先选定的区间内,根据价格触发条件进行买入和卖出,一旦价格离开该区间,其行为就会完全改变。

更紧密的网格间距能产生更多收入吗?

更紧密的间距会增加往返次数,并降低每次的毛利润,而往返成本保持不变。超过由价差设定的某个临界点后,增加的交易会从总额中扣除,而不是增加总额。


以上每个数字都来自一个存储的、有版本控制的、基于真实股票价格的查询;打开任何图表下方的SQL语句即可检查,或者在Strasmore终端上,针对您自己的股票列表,衡量行走距离与净变动的关系。

#grid trading#trading bots#automation#mean reversion#market data