Anchored VWAP公式与用途详解
了解Anchored VWAP如何从您选定的K线开始累计且不重置,查看通俗易懂的Python公式,并掌握移动锚点如何改变平均价格结果。
Anchored VWAP(锚定成交量加权平均价)是一种成交量加权平均价。它从您选定的一根K线开始累计,之后不会重置。交易时段VWAP会在每次开盘时重新开始,因此只能回答今天股票的平均成交价格。Anchored VWAP回答的是另一个问题:从您选定的起点开始,股票的平均成交价格是多少。
什么是Anchored VWAP?
两者使用完全相同的计算方法。从起点开始,将每根K线的价格乘以该K线的成交量,并持续累计。同时单独累计成交量。再用前一个累计值除以后一个累计值。具体而言,第n根K线的Anchored VWAP,是从锚定K线到第n根K线期间各根K线的价格乘以成交量之和,除以同一期间的成交量之和。
K线价格通常使用典型价格,即最高价、最低价和收盘价的平均值。如果数据源提供单根K线的VWAP,也可以使用该VWAP。
两个累计值中的数据都不会被移除。50日移动平均线每加入一个新观测值,就会剔除最早的观测值,因此均线会发生转向。Anchored VWAP只会继续累加,因此会永久保留历史数据。交易时段VWAP的计算方式相同,但会在每次开盘时将两个累计值清零。换言之,它是以开盘铃声为锚点的Anchored VWAP。
VWAP与Anchored VWAP有什么区别?
下方图表对苹果公司股票一个季度的日线K线同时计算了两者。session_vwap列是每个交易时段内的成交量加权平均价,每天都会得到一个新数值。anchored_vwap列从窗口期的第一个交易时段开始,并持续累计。
每个数字背后的完整 SQL
SELECT
toString(date) AS session_date,
formatDateTime(date, '%b %e') AS bar_label,
round(toFloat64(vwap), 2) AS session_vwap,
round(
sum(toFloat64(vwap) * toFloat64(volume)) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
/ sum(toFloat64(volume)) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
, 2) AS anchored_vwap
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'AAPL'
AND date >= '2026-04-01'
AND date <= '2026-06-30'
ORDER BY date在62个交易时段中,从Apr 1到Jun 30,日线序列随着盘面变化,而锚定序列则缓慢弯曲。第一天只有一个交易时段,因此该日的全部历史就是这一交易时段,锚定线从255.02开始。到窗口期结束时,锚定线达到286.86,而最后一个交易时段的VWAP为288.09。这揭示了两者的形态差异。锚定线起初与日线接近,随后随着纳入计算的成交量增加而逐渐变平。
人们通常把锚点放在哪里?
常见锚点包括财报发布日、跳空缺口的第一根K线、52周低点,以及新上市股票的首笔成交。它们背后的逻辑相同:从该时点之后进行交易的所有参与者,其平均成交价格就是Anchored VWAP。因此,当价格高于该线时,表示平均参与者处于账面盈利状态。
通常被忽略的是,锚点本身是一个判断,结论也会随锚点变化。下方图表分别将同一只股票锚定在最近12个月每个月的月初,并计算从该月开始到同一个固定终点的平均成交价格。
每个数字背后的完整 SQL
WITH
monthly AS (
SELECT
toStartOfMonth(date) AS m,
sum(toFloat64(vwap) * toFloat64(volume)) AS pv,
sum(toFloat64(volume)) AS vol
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'AAPL'
AND date >= '2025-07-01'
AND date <= '2026-06-30'
GROUP BY m
),
anchored AS (
SELECT
m,
sum(pv) OVER (ORDER BY m ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
/ sum(vol) OVER (ORDER BY m ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS avwap
FROM monthly
),
final_close AS (
SELECT toFloat64(argMax(close, date)) AS last_close
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'AAPL'
AND date >= '2026-06-01'
AND date <= '2026-06-30'
)
SELECT
formatDateTime(a.m, '%b %Y') AS anchor_from,
round(a.avwap, 2) AS anchored_vwap,
round(100 * (f.last_close / a.avwap - 1), 2) AS close_vs_avwap_pct
FROM anchored AS a
CROSS JOIN final_close AS f
ORDER BY a.m将锚点设在Jul 2025时,平均成交价格为259.52。窗口期最后一个收盘价相对于该价格为11.5%;当收盘价高于锚定线时,该数值为正。将锚点设在Jun 2026时,结果为294.07和-1.6%。同一只股票、同一个最后价格,却因锚点不同,对锚点之后持有者是否盈利得出了12种不同结论。计算公式不会替您选择锚点。事后选择的锚点可以被不断调整,直到支持图表想要表达的观点。因此,您阅读任何Anchored VWAP图表时,图注都应标明锚定日期。
如何用Python计算Anchored VWAP?
两条序列都可以通过一次遍历K线计算出来。下面的脚本使用标准库Python 3,不需要安装软件包,也不需要网络连接。脚本读取30根K线,并将交易时段序列与锚定序列并列输出,随后报告价格重新向上或向下穿过锚定线的第一根K线。示例中的K线是虚构数据,仅用于演示。将同一个循环用于真实K线时,计算方式不变。
"""Session VWAP and anchored VWAP from the same running totals. Standard library only."""
import csv
import io
# Illustrative bars, not market data: three sessions of ten 30 minute bars.
BARS = """bar,price,volume
2026-03-02 09:30,100.40,240000
2026-03-02 10:00,100.90,180000
2026-03-02 10:30,101.30,150000
2026-03-02 11:00,101.10,130000
2026-03-02 11:30,100.60,120000
2026-03-02 12:00,100.20,110000
2026-03-02 12:30,99.80,120000
2026-03-02 13:00,99.50,140000
2026-03-02 13:30,99.70,170000
2026-03-02 14:00,99.40,260000
2026-03-03 09:30,99.10,300000
2026-03-03 10:00,98.70,210000
2026-03-03 10:30,98.90,160000
2026-03-03 11:00,98.40,150000
2026-03-03 11:30,98.10,140000
2026-03-03 12:00,98.30,120000
2026-03-03 12:30,98.80,130000
2026-03-03 13:00,99.20,150000
2026-03-03 13:30,99.60,190000
2026-03-03 14:00,99.90,280000
2026-03-04 09:30,100.20,320000
2026-03-04 10:00,100.60,230000
2026-03-04 10:30,100.90,170000
2026-03-04 11:00,101.40,160000
2026-03-04 11:30,101.20,140000
2026-03-04 12:00,101.60,130000
2026-03-04 12:30,102.10,140000
2026-03-04 13:00,102.40,160000
2026-03-04 13:30,102.20,200000
2026-03-04 14:00,102.60,290000
"""
ANCHOR = "2026-03-02 10:30" # the bar the anchored series starts on
session_pv = session_vol = 0.0
anchor_pv = anchor_vol = 0.0
current_day = None
anchored = False
start_side = None
crossover = None
print(f"{'bar':<18}{'price':>8}{'session':>10}{'anchored':>10}")
for row in csv.DictReader(io.StringIO(BARS)):
stamp = row["bar"]
day, price, vol = stamp[:10], float(row["price"]), float(row["volume"])
if day != current_day: # the session totals reset at every open
session_pv = session_vol = 0.0
current_day = day
session_pv += price * vol
session_vol += vol
session_vwap = session_pv / session_vol
anchored = anchored or stamp == ANCHOR
if not anchored:
print(f"{stamp:<18}{price:>8.2f}{session_vwap:>10.2f}{'.':>10}")
continue
anchor_pv += price * vol # the anchored totals never reset
anchor_vol += vol
anchored_vwap = anchor_pv / anchor_vol
print(f"{stamp:<18}{price:>8.2f}{session_vwap:>10.2f}{anchored_vwap:>10.2f}")
gap = price - anchored_vwap
if start_side is None and abs(gap) > 1e-9:
start_side = gap > 0
elif start_side is not None and crossover is None and (gap > 0) != start_side:
crossover = stamp
print("first bar back through the anchored VWAP:", crossover or "no crossing here")
两对计数器体现了全部核心逻辑。session_pv和session_vol会在日期变化时清零。anchor_pv和anchor_vol则不会。之后的操作只是输出结果。
为什么锚定线会逐渐停止移动
Anchored VWAP随着时间推移越来越难以移动,这是由计算机制决定的。每根新K线在均线中的权重,等于自身成交量除以锚点之后的总成交量。第二天时,一个交易时段可能占总成交量的一半。200个交易时段之后,同一个交易时段的权重可能只剩不到百分之一。下方图表以10个交易时段为一个区间,计算苹果股票K线中该权重的变化。
每个数字背后的完整 SQL
WITH running AS (
SELECT
row_number() OVER (ORDER BY date) AS n,
toFloat64(volume)
/ sum(toFloat64(volume)) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS weight
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'AAPL'
AND date >= '2026-01-02'
AND date <= '2026-06-30'
)
SELECT
intDiv(n - 1, 10) * 10 + 10 AS bars_since_anchor,
round(100 * avg(weight), 2) AS newest_bar_weight_pct
FROM running
GROUP BY bars_since_anchor
ORDER BY bars_since_anchor前10个交易时段中,新纳入的K线平均占锚定线的30.09%,其中锚定K线本身占据全部权重。到第130个交易时段时,最新K线的权重降至2.14%。阅读这些图表时,可以得出两个结论。较早的锚点会形成几乎平直的线,对当前变化反应很小;较新的锚点则会使线条围绕价格快速波动,并频繁与价格交叉。两者没有谁更正确。它们只是处于不同历史阶段的同一个公式。若要直接判断当前成交量相对于正常水平的大小,可以使用日均成交量和相对成交量。
Anchored VWAP声称能够展示什么?
通常的说法是,它可以用于判断持仓状态。将锚点设在某个事件上后,该线代表自事件发生以来所有交易者的平均成交价格。因此,价格高于该线,表示多数持仓处于账面盈利状态;价格低于该线则相反。下方图表将5只家喻户晓的股票分别锚定在过去12个月内各自出现的最低日收盘价,并计算窗口期最后一个收盘价相对于对应平均价格的位置。
每个数字背后的完整 SQL
WITH
bars AS (
SELECT
ticker,
date,
toFloat64(vwap) AS px,
toFloat64(volume) AS vol,
toFloat64(close) AS c
FROM global_markets.stocks_daily_aggs
WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'KO', 'SPY')
AND date >= '2025-07-01'
AND date <= '2026-06-30'
),
lows AS (
SELECT
ticker,
argMin(date, c) AS low_date
FROM bars
GROUP BY ticker
)
SELECT
b.ticker AS symbol,
formatDateTime(l.low_date, '%b %e, %Y') AS anchored_at,
round(sumIf(b.px * b.vol, b.date >= l.low_date) / sumIf(b.vol, b.date >= l.low_date), 2) AS anchored_vwap,
round(argMax(b.c, b.date), 2) AS last_close,
round(100 * (argMax(b.c, b.date)
/ (sumIf(b.px * b.vol, b.date >= l.low_date) / sumIf(b.vol, b.date >= l.low_date)) - 1), 1) AS close_vs_avwap_pct
FROM bars AS b
INNER JOIN lows AS l ON b.ticker = l.ticker
GROUP BY b.ticker, l.low_date
ORDER BY close_vs_avwap_pct DESC这5只股票的结果从SPY的10.4%,到MSFT的1.3%不等。每个结果都以各自的锚定日期为基准。这种差异描述了已经发生的情况,但必须明确其局限性。Anchored VWAP是根据已经成交的价格和成交量计算出的描述性统计量,不是预测,也不是已被公开研究证明具有稳定优势的交易规则。它不包含价格和成交量历史中原本没有的信息,而产生该指标的锚点也是由人选择的。将其视为某个日期以来盘面的总结,是诚实的。将其视为结论,则说明真正发挥作用的是锚点。
常见问题
VWAP与Anchored VWAP有什么区别?
交易时段VWAP会在每次市场开盘时重置累计值,因此只描述当前交易日。Anchored VWAP从您选择的一根K线开始累计,之后不会重置,因此描述从该K线开始每个交易时段的平均成交价格。
交易者通常将VWAP锚定在哪里?
常见选择包括财报日期、跳空缺口的第一根K线、波段高点或波段低点,以及新上市股票的首个交易日。任何K线都可以作为锚点,而读者必须知道锚定日期,才能正确解读该线。
Anchored VWAP会在隔夜重置吗?
不会。这正是它的定义特征。价格乘以成交量的累计值,以及成交量的累计值,都会跨越收盘时间保留,并在下一个交易时段继续累计,无论中间间隔了多少个交易时段。
Anchored VWAP能预测什么吗?
它是描述性统计量,而不是预测工具。它总结的是锚点之后已经支付的价格。移动锚点会移动该线,也可能逆转表面上的结论。因此,任何基于该指标的判断,都取决于选择该锚定日期的依据是否充分。
可以用日线K线计算Anchored VWAP吗?
可以。本页图表使用日线K线,并将每个交易时段的VWAP作为K线价格。日内图表则使用分钟K线。无论使用哪种时间级别,计算公式都相同,变化的只是每次累加的增量大小。
上方每个图表都附有生成该图表的SQL,因此您可以打开图表并自行调整锚定日期。如果您想从某个关注的日期开始计算相同的累计值,可以在Strasmore终端中用自然语言提出请求。