Strasmore Research

Anchored VWAP สูตรและการใช้งาน

Anchored VWAP เริ่มคำนวณค่าเฉลี่ยตั้งแต่แท่งราคาที่เลือกและไม่รีเซ็ต อธิบายสูตรด้วย Python แบบเข้าใจง่าย พร้อมดูว่าการย้ายจุดเริ่มต้นเปลี่ยนผลลัพธ์อย่างไร

Anchored VWAP คือ ราคาเฉลี่ยถ่วงน้ำหนักด้วยปริมาณการซื้อขาย ที่เริ่มสะสมยอดตั้งแต่แท่งราคาที่คุณเลือก และไม่รีเซ็ตยอดเหล่านั้นอีกเลย ส่วน Session VWAP จะเริ่มคำนวณใหม่ทุกครั้งที่ตลาดเปิด จึงตอบได้เพียงว่าหุ้นมีการเปลี่ยนมือที่ราคาเฉลี่ยเท่าใดในวันนี้ ขณะที่ Anchored VWAP ตอบคำถามอีกแบบว่า ตั้งแต่วินาทีที่คุณเลือกเป็นจุดเริ่มต้น หุ้นมีการเปลี่ยนมือที่ราคาเฉลี่ยเท่าใด

Anchored VWAP คืออะไร

ทั้งสองแบบใช้การคำนวณเหมือนกัน เริ่มจากนำราคาของแต่ละแท่งตั้งแต่จุดเริ่มต้นคูณด้วยปริมาณการซื้อขายของแท่งนั้น แล้วสะสมเป็นยอดต่อเนื่อง ขณะเดียวกันให้สะสมปริมาณการซื้อขายแยกอีกยอดหนึ่ง จากนั้นนำยอดแรกหารด้วยยอดที่สอง กล่าวโดยเขียนเป็นสูตร Anchored VWAP ณ แท่ง n คือผลรวมของราคาคูณปริมาณการซื้อขายตั้งแต่แท่งที่เป็นจุดเริ่มต้นจนถึงแท่ง n หารด้วยผลรวมปริมาณการซื้อขายของแท่งเดียวกัน

ราคาของแท่งมักใช้เป็น typical price ซึ่งเป็นค่าเฉลี่ยของราคาสูงสุด ราคาต่ำสุด และราคาปิด หรือใช้ VWAP ของแท่งนั้นเอง หากแหล่งข้อมูลเผยแพร่ค่าไว้

ยอดทั้งสองจะไม่มีการลบข้อมูลออก ค่าเฉลี่ยเคลื่อนที่ 50 วันจะตัดข้อมูลเก่าที่สุดออกทุกครั้งที่เพิ่มข้อมูลใหม่ จึงสามารถเปลี่ยนทิศทางได้ ส่วน Anchored VWAP จะเพิ่มข้อมูลเท่านั้น ทำให้ข้อมูลในอดีตยังคงอยู่ตลอดเวลา Session VWAP ใช้การคำนวณแบบเดียวกัน แต่ตั้งยอดทั้งสองกลับเป็นศูนย์เมื่อเปิดตลาดทุกครั้ง จึงเทียบได้กับ Anchored VWAP ที่ใช้เสียงระฆังเปิดตลาดเป็นจุดเริ่มต้น

VWAP ต่างจาก Anchored VWAP อย่างไร

แผงด้านล่างคำนวณทั้งสองแบบจากแท่งราคารายวันของ Apple เป็นเวลาหนึ่งไตรมาส คอลัมน์ session_vwap คือราคาเฉลี่ยถ่วงน้ำหนักด้วยปริมาณการซื้อขายภายในแต่ละช่วงการซื้อขายเพียงช่วงเดียว จึงได้ค่าใหม่ทุกวัน คอลัมน์ anchored_vwap เริ่มต้นจากช่วงการซื้อขายแรกของช่วงเวลาที่แสดง แล้วสะสมต่อเนื่องจากจุดนั้น

คำสั่งดึงข้อมูลVWAP รายวันเทียบกับ VWAP ที่ยึดตามวันที่หนึ่งวัน (AAPL)
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
Run this yourself

ตลอด 62 ช่วงการซื้อขาย ตั้งแต่ Apr 1 ถึง Jun 30 ชุดข้อมูลรายวันเคลื่อนไหวไปตามเทปการซื้อขาย ขณะที่ชุดข้อมูลแบบ Anchored เคลื่อนตัวช้ากว่า เส้น Anchored เริ่มต้นที่ 255.02 เนื่องจากในวันแรกมีช่วงการซื้อขายเดียวเป็นข้อมูลทั้งหมด และไปสิ้นสุดที่ 286.86 เมื่อจบช่วงเวลา เทียบกับ Session VWAP สุดท้ายที่ 288.09 รูปทรงของเส้นคือประเด็นสำคัญ ในช่วงแรกเส้น Anchored เคลื่อนไหวใกล้กับเส้นรายวัน จากนั้นจะแบนราบลงเมื่อปริมาณการซื้อขายที่สะสมอยู่เบื้องหลังเพิ่มขึ้น

ผู้ใช้กำหนดจุดเริ่มต้นไว้ที่ใด

จุดเริ่มต้นที่นิยมใช้ ได้แก่ วันประกาศผลประกอบการ แท่งแรกของ gap จุดต่ำสุดในรอบ 52 สัปดาห์ หรือรายการซื้อขายแรกของหุ้นที่เพิ่งเข้าจดทะเบียน แนวคิดที่อยู่เบื้องหลังจุดเหล่านี้เหมือนกันทั้งหมด ผู้ที่ทำธุรกรรมหลังจากช่วงเวลานั้นซื้อขายที่ราคา Anchored VWAP โดยเฉลี่ย ดังนั้นราคาที่อยู่เหนือเส้นจึงหมายความว่า ผู้เข้าร่วมตลาดโดยเฉลี่ยมีกำไรที่ยังไม่รับรู้

ประเด็นที่มักไม่ได้กล่าวถึงคือ จุดเริ่มต้นเป็นดุลยพินิจ และผลลัพธ์จะเปลี่ยนไปตามจุดนั้น แผงด้านล่างกำหนดจุดเริ่มต้นของหุ้นตัวเดียวกันที่ต้นเดือนแต่ละเดือนในช่วง 12 เดือนล่าสุด แล้วคำนวณราคาเฉลี่ยที่มีการซื้อขายตั้งแต่เดือนนั้นจนถึงวันที่สิ้นสุดซึ่งกำหนดไว้คงที่

คำสั่งดึงข้อมูลหุ้นเดียวกันและราคาล่าสุดเท่ากัน โดยมีจุดยึดสิบสองแบบ (AAPL)
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
Run this yourself

การกำหนดจุดเริ่มต้นที่ Jul 2025 ทำให้ราคาเฉลี่ยที่มีการซื้อขายอยู่ที่ 259.52 และราคาปิดสุดท้ายของช่วงเวลาวัดได้ 11.5% เมื่อเทียบกับราคาดังกล่าว โดยตัวเลขจะเป็นบวกเมื่อราคาปิดอยู่เหนือเส้น การกำหนดจุดเริ่มต้นที่ Jun 2026 ให้ค่า 294.07 และ -1.6% หุ้นตัวเดียวกัน ราคาสุดท้ายเดียวกัน แต่ให้ข้อสรุป 12 แบบว่าผู้ถือครองตั้งแต่จุดเริ่มต้นมีสถานะเหนือราคาทุนหรือไม่ การคำนวณไม่ได้เลือกจุดเริ่มต้นให้คุณ จุดเริ่มต้นที่เลือกภายหลังสามารถเลื่อนได้จนกว่าจะสนับสนุนสิ่งที่กราฟต้องการสื่อ นั่นคือเหตุผลที่วันที่เริ่มต้นควรระบุไว้ในคำอธิบายของกราฟ Anchored VWAP ทุกกราฟที่คุณอ่าน

คำนวณ Anchored VWAP ใน Python อย่างไร

ข้อมูลทั้งสองชุดได้จากการวนผ่านแท่งราคาเพียงรอบเดียว สคริปต์ด้านล่างใช้ Python 3 จาก standard library โดยไม่มีแพ็กเกจเพิ่มเติมและไม่เชื่อมต่อเครือข่าย สคริปต์อ่านแท่งราคา 30 แท่ง แล้วแสดงชุดข้อมูล Session VWAP เทียบกับชุดข้อมูล Anchored VWAP จากนั้นรายงานแท่งแรกที่ราคาตัดกลับผ่านเส้น Anchored VWAP แท่งราคาที่ใช้เป็นข้อมูลสมมติสำหรับการสาธิต หากนำลูปเดียวกันไปใช้กับแท่งราคาจริง วิธีคำนวณจะไม่เปลี่ยนแปลง

"""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 จึงเคลื่อนที่ช้าลง

Anchored VWAP จะถูกผลักให้เคลื่อนที่ได้ยากขึ้นเมื่อมีอายุมากขึ้นด้วยเหตุผลทางกลไก แท่งใหม่แต่ละแท่งจะเข้ามาในค่าเฉลี่ยด้วยน้ำหนักเท่ากับปริมาณการซื้อขายของแท่งนั้นหารด้วยปริมาณการซื้อขายทั้งหมดตั้งแต่จุดเริ่มต้น ในวันที่สอง ช่วงการซื้อขายหนึ่งช่วงอาจคิดเป็นครึ่งหนึ่งของปริมาณทั้งหมด แต่เมื่อผ่านไป 200 ช่วงการซื้อขาย ช่วงเดียวกันนั้นจะมีน้ำหนักเพียงเศษเสี้ยวของ 1% แผงด้านล่างวัดน้ำหนักดังกล่าวจากแท่งราคาของ Apple โดยแบ่งเป็นช่วงละ 10 ช่วงการซื้อขาย

คำสั่งดึงข้อมูลเซสชันล่าสุดมีผลต่อ VWAP ที่ยึดจุดได้มากเพียงใด (AAPL)
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
Run this yourself

ในช่วง 10 ช่วงการซื้อขายแรก แท่งใหม่ที่เข้ามามีน้ำหนักเฉลี่ย 30.09% ของเส้น โดยแท่งที่เป็นจุดเริ่มต้นมีสัดส่วนทั้งหมดของน้ำหนัก เมื่อถึงช่วงการซื้อขายที่ 130 แท่งใหม่ล่าสุดมีน้ำหนักลดลงเหลือ 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
Run this yourself

หุ้นทั้ง 5 ตัวมีค่ากระจายตั้งแต่ SPY ที่ 10.4% ลงมาถึง MSFT ที่ 1.3% โดยแต่ละตัววัดเทียบกับวันที่เป็นจุดเริ่มต้นของตัวเอง ค่ากระจายดังกล่าวอธิบายสิ่งที่เกิดขึ้น แต่ควรระบุข้อจำกัดให้ชัดเจน Anchored VWAP เป็นสถิติเชิงพรรณนาที่คำนวณจากราคาและปริมาณการซื้อขายที่เกิดขึ้นแล้ว ไม่ใช่การคาดการณ์ และไม่ใช่กฎที่มีหลักฐานยืนยันว่ามีความได้เปรียบจากงานวิจัยที่เผยแพร่แล้ว ตัวชี้วัดนี้ไม่มีข้อมูลใดที่ประวัติราคาและปริมาณการซื้อขายไม่ได้มีอยู่ก่อนแล้ว อีกทั้งจุดเริ่มต้นที่ใช้คำนวณก็ถูกเลือกโดยบุคคล เมื่อใช้เป็นบทสรุปของเทปการซื้อขายนับจากวันที่หนึ่ง ตัวชี้วัดนี้ถือว่าตรงไปตรงมา แต่เมื่อใช้เป็นคำตัดสิน จุดเริ่มต้นต่างหากที่กำลังเป็นผู้พูด

คำถามที่พบบ่อย

VWAP ต่างจาก Anchored VWAP อย่างไร

Session VWAP จะรีเซ็ตยอดสะสมทุกครั้งที่ตลาดเปิด จึงอธิบายได้เฉพาะวันปัจจุบัน ส่วน Anchored VWAP จะเริ่มสะสมยอดจากแท่งราคาที่คุณเลือกและไม่รีเซ็ต จึงอธิบายราคาเฉลี่ยที่มีการซื้อขายในทุกช่วงการซื้อขายนับจากแท่งนั้น

นักเทรดกำหนดจุดเริ่มต้นของ VWAP ที่ใด

จุดที่นิยมใช้ ได้แก่ วันประกาศผลประกอบการ แท่งแรกของ gap จุดสูงสุดหรือจุดต่ำสุดของรอบการเคลื่อนไหว และวันแรกที่หุ้นเข้าซื้อขายในตลาด ทุกแท่งสามารถใช้เป็นจุดเริ่มต้นได้ และวันที่เป็นจุดเริ่มต้นคือข้อมูลที่ผู้อ่านต้องทราบเพื่อแปลความหมายของเส้น

Anchored VWAP รีเซ็ตข้ามคืนหรือไม่

ไม่รีเซ็ต และนี่คือคุณสมบัติที่กำหนดความเป็น Anchored VWAP ผลรวมสะสมของราคาคูณปริมาณการซื้อขายและผลรวมสะสมของปริมาณการซื้อขายจะต่อเนื่องข้ามเวลาปิดตลาด จากนั้นจึงคำนวณต่อในช่วงการซื้อขายถัดไป ไม่ว่าจะห่างจากช่วงก่อนหน้ากี่ช่วงการซื้อขาย

Anchored VWAP คาดการณ์อะไรได้หรือไม่

Anchored VWAP เป็นสถิติเชิงพรรณนา ไม่ใช่การคาดการณ์ ตัวชี้วัดนี้สรุปราคาที่มีการจ่ายไปแล้วนับจากจุดเริ่มต้น การเลื่อนจุดเริ่มต้นจะทำให้เส้นเปลี่ยนและอาจทำให้ข้อสรุปที่เห็นกลับด้าน ดังนั้นข้ออ้างใด ๆ ที่สร้างจากตัวชี้วัดนี้จะมีความน่าเชื่อถือได้เท่ากับเหตุผลที่ใช้สนับสนุนวันที่เป็นจุดเริ่มต้นเท่านั้น

คำนวณ Anchored VWAP จากแท่งราคารายวันได้หรือไม่

ได้ แผงต่าง ๆ ในหน้านี้ใช้แท่งราคารายวัน โดยใช้ Session VWAP ของแต่ละช่วงการซื้อขายเป็นราคาแท่ง ส่วนกราฟระหว่างวันจะใช้แท่งราคานาทีแทน สูตรเหมือนกันในทั้งสองความละเอียด ต่างกันเพียงขนาดของช่วงการเปลี่ยนแปลง


ทุกแผงด้านบนมาพร้อม SQL ที่ใช้สร้างข้อมูล คุณจึงเปิดดูและปรับวันที่เป็นจุดเริ่มต้นได้ด้วยตัวเอง หากต้องการคำนวณยอดสะสมแบบเดียวกันจากวันที่ที่สนใจ ให้ส่งคำขอเป็นภาษาอังกฤษทั่วไปบน Strasmore terminal