Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor · · Updated 2026-08-08

股票跳空缺口总会回补吗?数据告诉您答案

股票跳空缺口并不会在固定期限内总是回补。查看大盘股同日、五个、二十个和六十个交易日的回补率,以及可复现的SQL查询。

股票跳空缺口总会回补吗?在任何短到足以用于交易的时间范围内,都不是如此。这个说法之所以能流传,主要是因为人们通常不说明等待期限。缺口是今日开盘价与昨日常规交易时段收盘价之间的距离;回补则是价格重新穿过昨日收盘价的时刻。整个争论取决于读者愿意等待多久。

什么算作缺口,什么算作回补

缺口以今日开盘价相对于前一日收盘价的变动来衡量。昨日交易时段以一个价格结束,今日以另一个价格开盘,两者之间的差值就是缺口。它不是昨日盘中最高价或最低价与今日开盘价之间的距离。那是另一种、也容易得多的目标。将两者混为一谈,会让所谓的“缺口”变成普通交易日午餐前就能回补的价差。小缺口几乎出现在每个交易日:其他时区的交易、指数调整、个股新闻和除息调整,都会在美国市场休市期间推动公允价格变化。股票为何会隔夜跳空介绍了这种隔夜重新定价的来源。

回补是股票价格重新穿过前一日收盘价的第一个时刻。但如果不附带截止期限,这一定义并不完整。在无限期范围内,流动性较高的股票最终几乎都会穿过读者指定的任何价位。这样一来,“缺口总会回补”就变成了无法证伪的说法,而不是真实结论。下文每个数字都会注明观察期限。

全文使用同一组样本:八只美国大盘股,样本包含2021年1月至2026年2月的缺口交易日,并用常规交易时段的一分钟最高价和最低价检验回补。低于0.25%的缺口因四舍五入影响而剔除。

股票缺口总会在当天回补吗?

先看缺口大小。将所有缺口按幅度分组,再观察前一日收盘价是否在当日交易时段结束前再次被触及。

查询按缺口大小划分的当日缺口回补率:8只大盘股,2021—2026年
每个数字背后的完整 SQL
WITH sessions AS
(
    SELECT
        ticker,
        toDate(toTimeZone(window_start, 'America/New_York')) AS d,
        argMin(toFloat64(open), window_start)                AS session_open,
        argMax(toFloat64(close), window_start)               AS session_close,
        toFloat64(max(high))                                 AS session_high,
        toFloat64(min(low))                                  AS session_low
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'JPM', 'KO', 'WMT', 'XOM')
      AND window_start >= '2021-01-01'
      AND window_start <  '2026-07-01'
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) < 960
    GROUP BY ticker, d
),
gapped AS
(
    SELECT
        d,
        session_open,
        session_high,
        session_low,
        lagInFrame(session_close) OVER (PARTITION BY ticker ORDER BY d ASC
            ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prior_close
    FROM sessions
),
measured AS
(
    SELECT
        abs(100 * (session_open / prior_close - 1)) AS gap_pct,
        toUInt8(if(session_open > prior_close,
                   session_low  <= prior_close,
                   session_high >= prior_close))    AS filled_same_session
    FROM gapped
    WHERE prior_close > 0
      AND d <= toDate('2026-02-28')
      AND abs(100 * (session_open / prior_close - 1)) >= 0.25
)
SELECT
    multiIf(gap_pct < 0.5, '0.25 to 0.5%',
            gap_pct < 1,   '0.5 to 1%',
            gap_pct < 2,   '1 to 2%',
            gap_pct < 4,   '2 to 4%',
                           '4% or more')         AS gap_bucket,
    count()                                      AS gap_days,
    round(100 * avg(filled_same_session), 1)     AS same_session_fill_pct
FROM measured
GROUP BY gap_bucket
ORDER BY min(gap_pct) ASC
Run this yourself

样本中最小的缺口,即0.25%至0.5%的缺口,在74.6%的情况下于同一交易日回补,共涉及2381次。幅度达到4%或以上的缺口,在14.8%的情况下于同一交易日回补。图表中的下降趋势体现了大部分结论:缺口越小,股票越常在当天来回穿过该价位。换句话说,小缺口更接近噪声,而噪声更容易反转。

缺口需要多久才能回补?

延长截止期限,回补率只会提高。更长的观察窗口会增加回补案例,不会减少。真正的问题是,总回补数量中有多少发生得太晚,已经失去交易意义。

查询1%以上缺口回补比例:按等待时长划分
每个数字背后的完整 SQL
WITH sessions AS
(
    SELECT
        ticker,
        toDate(toTimeZone(window_start, 'America/New_York')) AS d,
        argMin(toFloat64(open), window_start)                AS session_open,
        argMax(toFloat64(close), window_start)               AS session_close,
        toFloat64(max(high))                                 AS session_high,
        toFloat64(min(low))                                  AS session_low
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'JPM', 'KO', 'WMT', 'XOM')
      AND window_start >= '2021-01-01'
      AND window_start <  '2026-07-01'
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) < 960
    GROUP BY ticker, d
),
paths AS
(
    SELECT
        d,
        session_open,
        session_high,
        session_low,
        lagInFrame(session_close) OVER (PARTITION BY ticker ORDER BY d ASC
            ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)                                                          AS prior_close,
        min(session_low)  OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING)   AS low_5,
        max(session_high) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 4 FOLLOWING)   AS high_5,
        min(session_low)  OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 19 FOLLOWING)  AS low_20,
        max(session_high) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 19 FOLLOWING)  AS high_20,
        min(session_low)  OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 59 FOLLOWING)  AS low_60,
        max(session_high) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 59 FOLLOWING)  AS high_60
    FROM sessions
),
gaps AS
(
    SELECT
        session_open > prior_close AS gap_up,
        prior_close,
        session_low,
        session_high,
        low_5,
        high_5,
        low_20,
        high_20,
        low_60,
        high_60
    FROM paths
    WHERE prior_close > 0
      AND d <= toDate('2026-02-28')
      AND abs(100 * (session_open / prior_close - 1)) >= 1
),
flags AS
(
    SELECT arrayJoin([
        (1, '1 session',   toUInt8(if(gap_up, session_low <= prior_close, session_high >= prior_close))),
        (2, '5 sessions',  toUInt8(if(gap_up, low_5  <= prior_close, high_5  >= prior_close))),
        (3, '20 sessions', toUInt8(if(gap_up, low_20 <= prior_close, high_20 >= prior_close))),
        (4, '60 sessions', toUInt8(if(gap_up, low_60 <= prior_close, high_60 >= prior_close)))
    ]) AS f
    FROM gaps
)
SELECT
    tupleElement(f, 2)                        AS horizon,
    count()                                   AS gaps_measured,
    round(100 * avg(tupleElement(f, 3)), 1)   AS filled_pct
FROM flags
GROUP BY horizon
ORDER BY min(tupleElement(f, 1)) ASC
Run this yourself

2191个幅度达到1%或以上的缺口中,34%在同一交易时段内回补,88.7%在60 sessions内回补。第二个数字通常会被引用,但引用时往往省略观察期限。六十个交易日大致相当于三个月。对于建立在单日错价基础上的头寸而言,这已经是较长的持有期。若一个缺口在第47个交易日才回补,即使股票此前已大幅朝相反方向运行,在该统计口径下仍然算作已回补。

噪声缺口与信息缺口属于两类不同群体

在交易平静、成交量正常的交易日,缺口通常只是小幅定价调整。若缺口源于财报新闻或收购要约,则意味着公司估值发生变化,市场已经没有一个旧价格等待回归。成交量可以较好地区分这两类缺口:如果整个市场都在进行重新定价,成交笔数通常会达到正常水平的数倍。

查询按缺口日成交量大小划分的缺口回补率
每个数字背后的完整 SQL
WITH sessions AS
(
    SELECT
        ticker,
        toDate(toTimeZone(window_start, 'America/New_York')) AS d,
        argMin(toFloat64(open), window_start)                AS session_open,
        argMax(toFloat64(close), window_start)               AS session_close,
        toFloat64(max(high))                                 AS session_high,
        toFloat64(min(low))                                  AS session_low,
        sum(toFloat64(volume))                               AS session_volume
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'JPM', 'KO', 'WMT', 'XOM')
      AND window_start >= '2021-01-01'
      AND window_start <  '2026-07-01'
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) < 960
    GROUP BY ticker, d
),
paths AS
(
    SELECT
        d,
        session_open,
        session_high,
        session_low,
        session_volume,
        lagInFrame(session_close) OVER (PARTITION BY ticker ORDER BY d ASC
            ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)                                                         AS prior_close,
        avg(session_volume) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN 21 PRECEDING AND 2 PRECEDING) AS normal_volume,
        min(session_low)  OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 19 FOLLOWING) AS low_20,
        max(session_high) OVER (PARTITION BY ticker ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 19 FOLLOWING) AS high_20
    FROM sessions
),
measured AS
(
    SELECT
        session_volume / normal_volume AS volume_ratio,
        toUInt8(if(session_open > prior_close, session_low <= prior_close, session_high >= prior_close)) AS filled_same_session,
        toUInt8(if(session_open > prior_close, low_20 <= prior_close, high_20 >= prior_close))           AS filled_20_sessions
    FROM paths
    WHERE prior_close > 0
      AND normal_volume > 0
      AND d >= toDate('2021-03-01')
      AND d <= toDate('2026-02-28')
      AND abs(100 * (session_open / prior_close - 1)) >= 1
)
SELECT
    multiIf(volume_ratio < 1.5, 'Under 1.5x normal',
            volume_ratio < 3,   '1.5x to 3x normal',
                                '3x or more')        AS volume_regime,
    count()                                          AS gap_days,
    round(100 * avg(filled_same_session), 1)         AS same_session_fill_pct,
    round(100 * avg(filled_20_sessions), 1)          AS within_20_sessions_fill_pct
FROM measured
WHERE isFinite(volume_ratio)
GROUP BY volume_regime
ORDER BY min(volume_ratio) ASC
Run this yourself

在成交量低于股票正常成交量1.5倍的情况下,幅度达到1%或以上的缺口有35.9%在同一交易时段内回补。在成交量达到正常水平3倍或以上的情况下,同样幅度的缺口有15.3%在同一交易时段内回补,并有45.8%在20个交易日内回补;这类缺口占全部样本的59。高成交量组包含财报缺口和交易消息缺口。将两组平均为一个数字,无法准确描述其中任何一组。

为何交易时段开盘几分钟会扭曲缺口统计

记录在上午9:31的回补,可靠性较低。开盘价来自集合竞价。集合竞价将隔夜排队的订单集中撮合,并为所有订单确定一个价格。我们的开盘集合竞价说明介绍了相关机制。撮合完成后的几分钟内,报价价差通常处于全天最宽水平。一笔很小的成交就可能形成一个最高价或最低价,而实际并没有足够的成交量在该价位成交。开盘时价差会扩大介绍了此时的报价为何如此稀疏。

下图展示了该篮子股票自身成交记录中的形态:截至2025年,按每15分钟时间段统计的一分钟平均高低价区间,单位为基点。一基点等于百分之一个百分点。

查询2025年按时段划分的平均一分钟波动幅度和成交量
每个数字背后的完整 SQL
SELECT
    formatDateTime(toStartOfInterval(toTimeZone(window_start, 'America/New_York'), INTERVAL 15 MINUTE), '%H:%i') AS et_time,
    round(10000 * avg(toFloat64(high) / toFloat64(low) - 1), 1) AS avg_range_bps,
    round(avg(toFloat64(volume)) / 1000, 1)                     AS avg_volume_k
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'AMZN', 'JPM', 'KO', 'WMT', 'XOM')
  AND window_start >= '2025-01-01'
  AND window_start <  '2026-01-01'
  AND toFloat64(low) > 0
  AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
       + toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570
  AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
       + toMinute(toTimeZone(window_start, 'America/New_York'))) < 960
GROUP BY et_time
ORDER BY et_time ASC
Run this yourself

开盘时间段每分钟平均区间为24.4个基点,而12:30时间段为6.9个基点;前者每分钟成交量为303.9千股,后者为69.6千股。若回补发生在第一个时间段内,其依据是当天最不可靠的价格。上文的当日回补数据包含这些分钟,因此回补率会略微偏高。这一限制适用于所有当日回补统计,包括本项统计。

将缺口视为交易机会前应检查什么

  1. 观察期限。没有截止期限的回补率,不构成统计数据。
  2. 样本群体。应确认信息缺口是否与平静交易日的缺口分开,以及区分标准是什么。
  3. 衡量方法。应确认回补是否依据真实成交区间检验,以及是否计入交易时段开盘后的最初几分钟。
  4. 存续样本。应确认样本是否只包含今天仍在交易的股票,因为这会悄然删除从未回补的缺口。

更准确的说法比“缺口总会回补”更有限。普通成交量下的小缺口通常会频繁且快速地反转。高成交量下的大缺口属于重新定价,往往会持续数月。若想查看当前哪些股票正在出现缺口,本周涨跌幅最大的股票页面会跟踪本周情况;市场如何从崩盘中复苏则将同样的期限纪律应用于指数回撤。

常见问题

股票缺口总会回补吗?

不会。在本文样本中,幅度达到1%或以上的缺口,有88.7%在60 sessions内重新穿过前一日收盘价。这意味着约三个月后仍有一部分缺口没有回补。“总会”这一说法只有在不设时间限制时才成立,而一旦没有时间限制,就无法进行检验。

缺口需要多久才能回补?

这取决于缺口本身。在本文样本中,幅度达到1%或以上的缺口有34%在同一交易时段内回补,其余回补分布在随后的数周和数月内。小缺口主要集中在当日回补,高成交量缺口的回补速度最慢。

普通缺口与突破缺口有什么区别?

图表术语会根据背景对缺口进行分类。普通缺口出现在成交量正常、没有特定新闻的普通交易日。突破缺口则伴随新信息和高成交量,通常突破股票此前维持了一段时间的价格区间。上方图表中的成交量分组,是对这一差异的量化表达。

为什么不同来源的缺口回补统计差异很大?

四项选择会显著影响结果:回补观察期限、股票样本、统计期间,以及缺口是相对于前一日收盘价衡量,还是相对于前一日最高价和最低价衡量。缺少其中任何一项的信息,所引用的回补率就无法与另一项统计进行比较。


这些数字的计算方法

交易时段由纽约时间常规交易时段内的一分钟K线构成。开盘价是常规交易时段第一根K线的开盘价,收盘价是最后一根K线的收盘价,当日最高价和最低价则是这些K线中的极值。每个缺口都相对于同一ticker前一交易时段的收盘价计算。

5个、20个和60个交易日的观察期限都包含缺口发生当日。缺口交易日统计截至2026年2月底,而成交记录延续至2026年6月。因此,期限面板中的每个缺口后面都至少有60个可用交易日,不会因数据不足而被计为未回补。

第三个面板中的正常成交量,是缺口发生日前两日结束的连续20个交易日常规交易时段平均成交量。这样可以排除缺口当日及前一交易日对自身基准的影响。

样本篮子由八只流动性较高的大盘股组成。小盘股出现缺口的频率和回补方式可能不同,因此这些回补率不能直接外推至小盘股,必须对小盘股重新进行同样的检验。

本文每个面板下方都附有完整且精确的SQL。若您想对自己关注的ticker运行同一项测试,可以在Strasmore terminal中用自然语言提问。

#gaps#gap fill#opening auction#overnight returns#technical analysis