XAULearn

VWAP Distribution Levels v1.2 · ซอร์สโค้ด

Pine Script ต้นฉบับ

ไฟล์นี้ถูกคัดลอกจากต้นฉบับใน G:\Trader\PineSCript\ ตอนสร้างเว็บ จึงเป็นโค้ดชุดเดียวกับที่ทำงานอยู่บนชาร์ตจริง ณ วันที่ปรับปรุง

VWAP_DistLevels_v1_2.pine 332 บรรทัด 24 KB ต้นฉบับแก้ไขล่าสุด 6 ตุลาคม 2569 ดาวน์โหลด .pine

Pine Script ยังไม่มีไวยากรณ์เฉพาะสำหรับตัวไฮไลต์ที่ใช้ จึงไฮไลต์ด้วยไวยากรณ์ TypeScript ซึ่งใกล้เคียงกันพอที่จะอ่านง่าย ตัวเลขบรรทัดตรงกับไฟล์จริง ใช้อ้างอิงในบทเรียนได้ เช่น vwap-dl-v1-2.pine:120

สารบัญส่วนของโค้ด (12)
  1. 8 ทำไมตัวนี้ต่างจากอินดิเคเตอร์ VWAP-SD ทั่วไป — สองจุด และทั้งคู่วัดมาแล้ว
  2. 10 ① σ รู้ล่วงหน้า ไม่ใช่ σ ในเซสชัน
  3. 20 ② ตัวคูณวัดจากข้อมูล ไม่ใช่ควอนไทล์เกาส์เซียน — และมี "สองเกณฑ์"
  4. 43 ① ขอบเขตที่แสดง
  5. 51 ② เครื่องประเมิน σ
  6. 62 ③ ตัวคูณ
  7. 71 ④ สี
  8. 85 เวลานิวยอร์ก และรหัสเซสชัน
  9. 87 ⭐ GVZ — ความผันผวนแฝงของออปชันทอง · ใช้แท่งวันที่ปิดแล้วเท่านั้น (lookahead_off)
  10. 104 คลังพิสัยย้อนหลัง — หนึ่งคลังต่อชนิดเซสชัน บวกอีกหนึ่งของขอบเขตวัน
  11. 196 ตัวคูณ — คาลิเบรตที่ความคุ้มครองสองฝั่ง 50/70/85/95/99%
  12. 260 วาด
// © geenabhud · XAULearn
//@version=6
// ⚑ ชื่อเวอร์ชันมีที่เดียว — v1.0→v1.1→v1.2 เคยลืมแก้หัวตาราง ทำให้เครื่องมือรายงานตัวเองผิด
VER = "v1.2"
indicator("VWAP Distribution Levels " + VER, "VWAP-DL " + VER, overlay = true)

// ════════════════════════════════════════════════════════════════════════════
//  ทำไมตัวนี้ต่างจากอินดิเคเตอร์ VWAP-SD ทั่วไป — สองจุด และทั้งคู่วัดมาแล้ว
//
//  ① σ รู้ล่วงหน้า ไม่ใช่ σ ในเซสชัน
//     สูตรมาตรฐาน dev = sqrt(Σvp²/Σv − vwap²) เป็นตัวหารที่พองตามตัวเศษ
//     ราคาวิ่งหนีไกล σ ก็กว้างตาม แถบจึงกว้างขึ้นพอดีกับตอนที่เกิดเหตุ
//     ผลคือ z ไม่เคยใหญ่ โดยโครงสร้าง
//     วัดบนทอง M1 ปี 2015-19 (1.77 ล้านแท่ง): ส่วนเกินความโก่งของ
//     (close − VWAP)/σ_สะสม = −0.3 … −0.5 คือ หางบางกว่าเกาส์เซียน
//     เปลี่ยนเป็น σ จากพิสัยเซสชันเดียวกัน 20 ครั้งก่อน ได้ +4.0 (นิวยอร์ก)
//     +6.8 (ลอนดอน) +68 (เอเชีย) ซึ่งคือหางอ้วนของจริง
//     ผลพลอยได้: แถบมีความกว้างเต็มตั้งแต่แท่งแรกของเซสชัน
//
//  ② ตัวคูณวัดจากข้อมูล ไม่ใช่ควอนไทล์เกาส์เซียน — และมี "สองเกณฑ์"
//
//     ต่อแท่ง (ค่าตั้งต้น)  "ราคาปิดอยู่ในกรอบกี่ % ของแท่ง"
//                           คือคำถามที่ตามองบนจอ · NY 0.58/0.98/1.54/2.44/3.95
//     ต่อเซสชัน             "ทั้งเซสชันไม่แตะกรอบกี่ %"
//                           คือคำถามขอบเขตความเสี่ยง · NY 2.20/2.85/3.73/5.28/7.17
//     เกาส์เซียน                                        0.67/1.04/1.44/1.96/2.58
//
//     ⚑ v1.0 ใช้เกณฑ์ต่อเซสชันเป็นค่าตั้งต้น ซึ่งกว้างเกินกว่าจะอ่านบนจอ
//        (L5 ห่าง VWAP ราว 100$ ที่ความผันผวนปี 2026) · v1.1 ตั้งต้นที่ต่อแท่ง
//
//     ⭐ ลายเซ็นหางอ้วนอ่านได้จากเกณฑ์ต่อแท่งตรง ๆ: L1 **แคบกว่า** เกาส์เซียน
//        (0.58 < 0.67) แต่ L5 **กว้างกว่า 1.5 เท่า** (3.95 > 2.58)
//        = มวลกระจุกกลางมากขึ้น และไปไกลมากขึ้น พร่องตรงกลางทาง
//        ช่วงไดนามิก L5/L1 = 6.8 เท่า ขณะที่เกาส์เซียนให้แค่ 3.85 เท่า
//
//  ⚑ ตัวนี้บอกว่าราคา "ไป" ถึงไหน ไม่ได้บอกว่าราคา "ตอบสนอง" ที่นั่น
//     ใช้เป็นสเกลความเสี่ยงได้ทันที (SL/TP ควรห่างเท่าไร)
//     ใช้เป็นสัญญาณต้องผ่านการทดสอบก่อน — L5 แตะ 1% ของเซสชัน = พิสูจน์ไม่ได้
//
//  คู่แฝด Python: edge/vwap_dist.py · ตารางตัวคูณตรงกันทุกตัว
// ════════════════════════════════════════════════════════════════════════════

// ───── ① ขอบเขตที่แสดง ─────────────────────────────────────────────────────
g1 = "① ขอบเขต"
i_sess_on  = input.bool(true,  "แถบเซสชัน (เอเชีย/ลอนดอน/นิวยอร์ก)", group = g1)
i_day_on   = input.bool(true,  "แถบวัน (ยึด 17:00 นิวยอร์ก)", group = g1)
i_day_lvls = input.bool(false, "วาดระดับของขอบเขตวันด้วย", group = g1,
     tooltip = "ปิดไว้ = เห็นแค่เส้น VWAP ของวัน · เปิด = เพิ่มอีก 10 เส้น")
i_lvl_max  = input.int(5, "วาดถึงระดับที่", minval = 1, maxval = 5, group = g1)

// ───── ② เครื่องประเมิน σ ──────────────────────────────────────────────────
g2 = "② σ ที่รู้ล่วงหน้า"
i_lb  = input.int(20, "จำนวนเซสชันย้อนหลัง", minval = 5, maxval = 60, group = g2,
     tooltip = "ค่ากลางของพิสัยเซสชันเดียวกัน N ครั้งก่อน · ไม่มีข้อมูลเซสชันปัจจุบัน")
i_div = input.float(4.0, "พิสัย → σ หารด้วย", minval = 2.0, maxval = 6.0, step = 0.25,
     group = g2, tooltip = "พิสัย ≈ 4σ สำหรับการเดินสุ่ม")
i_src = input.source(hl2, "ราคาที่ใช้ถ่วงน้ำหนัก", group = g2)
i_gvz = input.bool(true, "ปรับ σ ด้วยความผันผวนแฝง GVZ", group = g2,
     tooltip = "GVZ หารด้วยค่าเฉลี่ย 20 วันของตัวเอง แล้วคูณเข้ากับ σ // วัดแล้วความเบี่ยงเบนของความคุ้มครองลดจาก 1.08 เหลือ 0.90 จุด% และดีขึ้น 14 จาก 15 ช่องปี-เซสชัน // ปิดได้ถ้าสัญลักษณ์ CBOE:GVZ ใช้ไม่ได้")
i_gvzsym = input.symbol("CBOE:GVZ", "สัญลักษณ์ความผันผวนแฝง", group = g2)

// ───── ③ ตัวคูณ ────────────────────────────────────────────────────────────
g3 = "③ ตัวคูณ (วัดจาก DEV 2015-19)"
i_calib = input.string("ต่อแท่ง", "เกณฑ์คาลิเบรต", options = ["ต่อแท่ง", "ต่อเซสชัน"],
     group = g3, tooltip = "ต่อแท่ง = ราคาปิดอยู่ในกรอบกี่ % ของแท่ง คือสิ่งที่ตามองบนจอ // ต่อเซสชัน = ทั้งเซสชันไม่แตะกรอบกี่ % คือขอบเขตความเสี่ยง กว้างกว่าเกือบเท่าตัว")
i_gauss = input.bool(false, "ใช้ตัวคูณเกาส์เซียนแทน (ด่านควบคุม)", group = g3,
     tooltip = "0.67/1.04/1.44/1.96/2.58 · เปิดเพื่อเห็นว่าเกาส์เซียนแคบแค่ไหน")
i_cmp = input.bool(false, "เทียบกับ σ สะสมแบบเดิมที่ระดับ 3", group = g3,
     tooltip = "เส้นกากบาท = สิ่งที่อินดิเคเตอร์ VWAP-SD ทั่วไปวาด ณ ตัวคูณเดียวกัน")

// ───── ④ สี ────────────────────────────────────────────────────────────────
g4 = "④ สี"
c_vw  = input.color(#ffffff, "VWAP เซสชัน", group = g4)
c_dvw = input.color(#ffb300, "VWAP วัน", group = g4)
c_up  = input.color(#ef5350, "ระดับฝั่งบน", group = g4)
c_dn  = input.color(#26a69a, "ระดับฝั่งล่าง", group = g4)
i_fill = input.int(93, "ความโปร่งของพื้นที่ระบาย", minval = 70, maxval = 100, group = g4)
i_fill_to = input.int(2, "ระบายถึงระดับที่", minval = 0, maxval = 5, group = g4,
     tooltip = "0 = ไม่ระบายเลย · ระบายทั้ง 5 ชั้นทำให้จอทึบจนบังแท่งเทียน")

g5 = "⑤ ตาราง"
i_tbl = input.bool(true, "แสดงตารางสถานะ", group = g5)

// ════════════════════════════════════════════════════════════════════════════
//  เวลานิวยอร์ก และรหัสเซสชัน
// ════════════════════════════════════════════════════════════════════════════
// ⭐ GVZ — ความผันผวนแฝงของออปชันทอง · ใช้แท่งวันที่ปิดแล้วเท่านั้น (lookahead_off)
gvz_raw = request.security(i_gvzsym, "D", close[1], barmerge.gaps_off, barmerge.lookahead_off)
gvz_avg = request.security(i_gvzsym, "D", ta.sma(close[1], 20), barmerge.gaps_off, barmerge.lookahead_off)
gvz_r = i_gvz and not na(gvz_raw) and not na(gvz_avg) and gvz_avg > 0 ? gvz_raw / gvz_avg : 1.0

TZ = "America/New_York"
hm = hour(time, TZ) * 100 + minute(time, TZ)
// 0 = เอเชีย (17:00–03:00) · 1 = ลอนดอน (03:00–08:00) · 2 = นิวยอร์ก (08:00–17:00)
sid = hm >= 800 and hm < 1700 ? 2 : hm >= 300 and hm < 800 ? 1 : 0

new_sess = ta.change(sid) != 0 or barstate.isfirst
// วันเทรดเริ่มเมื่อเข้าเซสชันเอเชีย = 17:00 นิวยอร์ก · กันเวลาออมแสงเพราะ
// อ่าน hm จากโซนเวลา ไม่ใช่จากออฟเซ็ตคงที่ · และไม่ใช้แท่ง D1 ของผู้ให้ข้อมูล
// (แท่ง D1 ติดป้ายด้วยเวลาเปิด การ join แบบวันปฏิทินคืออ่านอนาคต 17 ชม.)
new_day = (sid == 0 and nz(sid[1], -1) != 0) or barstate.isfirst

// ════════════════════════════════════════════════════════════════════════════
//  คลังพิสัยย้อนหลัง — หนึ่งคลังต่อชนิดเซสชัน บวกอีกหนึ่งของขอบเขตวัน
// ════════════════════════════════════════════════════════════════════════════
var array<float> hist_asia = array.new_float()
var array<float> hist_lon  = array.new_float()
var array<float> hist_ny   = array.new_float()
var array<float> hist_day  = array.new_float()

push(array<float> a, float v) =>
    if not na(v) and v > 0
        array.push(a, v)
        if array.size(a) > i_lb
            array.shift(a)

sigma_of(array<float> a) =>
    float base = array.size(a) >= i_lb ? array.median(a) / i_div : float(na)
    na(base) ? float(na) : base * gvz_r

// ── ตัวสะสมของเซสชัน ───────────────────────────────────────────────────────
var float s_anchor = na
var float s_wsum   = 0.0
var float s_wdsum  = 0.0
var float s_wd2    = 0.0
var float s_hi     = na
var float s_lo     = na
var float s_sig    = na
var int   s_id     = 0

// ── ตัวสะสมของวัน ──────────────────────────────────────────────────────────
var float d_anchor = na
var float d_wsum   = 0.0
var float d_wdsum  = 0.0
var float d_hi     = na
var float d_lo     = na
var float d_sig    = na

if new_sess
    // ปิดเซสชันก่อนหน้า: เก็บพิสัยเข้าคลังของชนิดนั้น แล้วค่อยรีเซ็ต
    if not na(s_hi) and not na(s_lo)
        float r = s_hi - s_lo
        if s_id == 0
            push(hist_asia, r)
        else if s_id == 1
            push(hist_lon, r)
        else
            push(hist_ny, r)
    s_id := sid
    s_anchor := i_src
    s_wsum := 0.0
    s_wdsum := 0.0
    s_wd2 := 0.0
    s_hi := high
    s_lo := low
    // σ ของเซสชันที่กำลังเปิด — รู้ค่าทันทีตั้งแต่แท่งแรก
    float sg = sid == 0 ? sigma_of(hist_asia) : sid == 1 ? sigma_of(hist_lon) : sigma_of(hist_ny)
    s_sig := sg

if new_day
    if not na(d_hi) and not na(d_lo)
        push(hist_day, d_hi - d_lo)
    d_anchor := i_src
    d_wsum := 0.0
    d_wdsum := 0.0
    d_hi := high
    d_lo := low
    d_sig := sigma_of(hist_day)

// ── สะสม · หักจุดยึดก่อนยกกำลังสอง เลี่ยงการสูญเสียนัยสำคัญ ────────────────
// สูตร Σvp²/Σv − vwap² ลบเลขใหญ่สองตัวที่เกือบเท่ากัน (ทองราคา 4 หลัก ⇒
// p² ราว 1e7 แต่ความแปรปรวนราว 1) · max(...,0) ในสคริปต์ทั่วไปคือร่องรอย
// ว่าเจ้าของเคยเห็นมันติดลบ · หักจุดยึดก่อนแล้วปัญหานี้หายไป
w = math.max(nz(volume), 1e-9)
ds = i_src - s_anchor
s_wsum += w
s_wdsum += w * ds
s_wd2 += w * ds * ds
s_hi := math.max(nz(s_hi, high), high)
s_lo := math.min(nz(s_lo, low), low)

dd = i_src - d_anchor
d_wsum += w
d_wdsum += w * dd
d_hi := math.max(nz(d_hi, high), high)
d_lo := math.min(nz(d_lo, low), low)

s_mu = s_wsum > 0 ? s_wdsum / s_wsum : 0.0
s_vwap = s_anchor + s_mu
d_vwap = d_anchor + (d_wsum > 0 ? d_wdsum / d_wsum : 0.0)
// σ สะสมแบบเดิม — เก็บไว้เทียบเท่านั้น ไม่ได้ใช้วางระดับ
s_var = s_wsum > 0 ? s_wd2 / s_wsum - s_mu * s_mu : 0.0
s_sd_live = math.sqrt(math.max(s_var, 0.0))

// ════════════════════════════════════════════════════════════════════════════
//  ตัวคูณ — คาลิเบรตที่ความคุ้มครองสองฝั่ง 50/70/85/95/99%
// ════════════════════════════════════════════════════════════════════════════
mult(int which, int k) =>
    // which: 0=เอเชีย 1=ลอนดอน 2=นิวยอร์ก 3=วัน · k: 1..5
    float m = na
    bool bar_mode = i_calib == "ต่อแท่ง"
    if i_gauss
        m := k == 1 ? 0.67 : k == 2 ? 1.04 : k == 3 ? 1.44 : k == 4 ? 1.96 : 2.58
    else if bar_mode and which == 0
        m := i_gvz ? (k == 1 ? 0.49 : k == 2 ? 0.84 : k == 3 ? 1.30 : k == 4 ? 2.02 : 3.22) : (k == 1 ? 0.48 : k == 2 ? 0.83 : k == 3 ? 1.29 : k == 4 ? 2.03 : 3.31)
    else if bar_mode and which == 1
        m := i_gvz ? (k == 1 ? 0.54 : k == 2 ? 0.91 : k == 3 ? 1.41 : k == 4 ? 2.20 : 3.47) : (k == 1 ? 0.53 : k == 2 ? 0.90 : k == 3 ? 1.39 : k == 4 ? 2.21 : 3.54)
    else if bar_mode and which == 2
        m := i_gvz ? (k == 1 ? 0.58 : k == 2 ? 0.99 : k == 3 ? 1.56 : k == 4 ? 2.46 : 3.91) : (k == 1 ? 0.58 : k == 2 ? 0.98 : k == 3 ? 1.54 : k == 4 ? 2.44 : 3.95)
    else if bar_mode
        m := i_gvz ? (k == 1 ? 0.44 : k == 2 ? 0.79 : k == 3 ? 1.31 : k == 4 ? 2.25 : 3.74) : (k == 1 ? 0.44 : k == 2 ? 0.78 : k == 3 ? 1.30 : k == 4 ? 2.25 : 3.72)
    else if which == 0
        m := k == 1 ? 2.14 : k == 2 ? 2.77 : k == 3 ? 3.54 : k == 4 ? 5.02 : 7.44
    else if which == 1
        m := k == 1 ? 2.28 : k == 2 ? 2.92 : k == 3 ? 3.69 : k == 4 ? 5.00 : 7.48
    else if which == 2
        m := k == 1 ? 2.20 : k == 2 ? 2.85 : k == 3 ? 3.73 : k == 4 ? 5.28 : 7.17
    else
        m := k == 1 ? 2.28 : k == 2 ? 2.92 : k == 3 ? 3.78 : k == 4 ? 5.09 : 7.36
    m

lvl(float base, float sig, int which, int k, bool up, bool on) =>
    float m = mult(which, k)
    float r = na
    if on and k <= i_lvl_max and not na(sig)
        r := up ? base + m * sig : base - m * sig
    r

sOK = i_sess_on
dOK = i_day_on and i_day_lvls

su1 = lvl(s_vwap, s_sig, s_id, 1, true, sOK)
sd1 = lvl(s_vwap, s_sig, s_id, 1, false, sOK)
su2 = lvl(s_vwap, s_sig, s_id, 2, true, sOK)
sd2 = lvl(s_vwap, s_sig, s_id, 2, false, sOK)
su3 = lvl(s_vwap, s_sig, s_id, 3, true, sOK)
sd3 = lvl(s_vwap, s_sig, s_id, 3, false, sOK)
su4 = lvl(s_vwap, s_sig, s_id, 4, true, sOK)
sd4 = lvl(s_vwap, s_sig, s_id, 4, false, sOK)
su5 = lvl(s_vwap, s_sig, s_id, 5, true, sOK)
sd5 = lvl(s_vwap, s_sig, s_id, 5, false, sOK)

du1 = lvl(d_vwap, d_sig, 3, 1, true, dOK)
dl1 = lvl(d_vwap, d_sig, 3, 1, false, dOK)
du2 = lvl(d_vwap, d_sig, 3, 2, true, dOK)
dl2 = lvl(d_vwap, d_sig, 3, 2, false, dOK)
du3 = lvl(d_vwap, d_sig, 3, 3, true, dOK)
dl3 = lvl(d_vwap, d_sig, 3, 3, false, dOK)
du4 = lvl(d_vwap, d_sig, 3, 4, true, dOK)
dl4 = lvl(d_vwap, d_sig, 3, 4, false, dOK)
du5 = lvl(d_vwap, d_sig, 3, 5, true, dOK)
dl5 = lvl(d_vwap, d_sig, 3, 5, false, dOK)

// เส้นเทียบ: σ สะสม ที่ตัวคูณระดับ 3 ตัวเดียวกัน
cm3 = mult(s_id, 3)
cu3 = i_cmp and i_sess_on ? s_vwap + cm3 * s_sd_live : na
cl3 = i_cmp and i_sess_on ? s_vwap - cm3 * s_sd_live : na

// ════════════════════════════════════════════════════════════════════════════
//  วาด
// ════════════════════════════════════════════════════════════════════════════
pV  = plot(i_sess_on ? s_vwap : na, "VWAP เซสชัน", c_vw, 2)
pU1 = plot(su1, "เซสชัน +L1 (50%)", color.new(c_up, 35), 1)
pD1 = plot(sd1, "เซสชัน −L1 (50%)", color.new(c_dn, 35), 1)
pU2 = plot(su2, "เซสชัน +L2 (70%)", color.new(c_up, 30), 1)
pD2 = plot(sd2, "เซสชัน −L2 (70%)", color.new(c_dn, 30), 1)
pU3 = plot(su3, "เซสชัน +L3 (85%)", color.new(c_up, 20), 1)
pD3 = plot(sd3, "เซสชัน −L3 (85%)", color.new(c_dn, 20), 1)
pU4 = plot(su4, "เซสชัน +L4 (95%)", color.new(c_up, 10), 2)
pD4 = plot(sd4, "เซสชัน −L4 (95%)", color.new(c_dn, 10), 2)
pU5 = plot(su5, "เซสชัน +L5 (99%)", c_up, 2)
pD5 = plot(sd5, "เซสชัน −L5 (99%)", c_dn, 2)

plot(i_day_on ? d_vwap : na, "VWAP วัน", c_dvw, 2)
plot(du1, "วัน +L1", color.new(c_dvw, 55), 1)
plot(dl1, "วัน −L1", color.new(c_dvw, 55), 1)
plot(du2, "วัน +L2", color.new(c_dvw, 50), 1)
plot(dl2, "วัน −L2", color.new(c_dvw, 50), 1)
plot(du3, "วัน +L3", color.new(c_dvw, 40), 1)
plot(dl3, "วัน −L3", color.new(c_dvw, 40), 1)
plot(du4, "วัน +L4", color.new(c_dvw, 25), 1)
plot(dl4, "วัน −L4", color.new(c_dvw, 25), 1)
plot(du5, "วัน +L5", color.new(c_dvw, 10), 2)
plot(dl5, "วัน −L5", color.new(c_dvw, 10), 2)

plot(cu3, "เทียบ σ สะสม +L3", color.new(color.gray, 20), 1, plot.style_cross)
plot(cl3, "เทียบ σ สะสม −L3", color.new(color.gray, 20), 1, plot.style_cross)

f1 = i_fill_to >= 1 ? i_fill : 100
f2 = i_fill_to >= 2 ? i_fill : 100
f3 = i_fill_to >= 3 ? i_fill : 100
f4 = i_fill_to >= 4 ? i_fill : 100
f5 = i_fill_to >= 5 ? i_fill : 100
fill(pV, pU1, color.new(c_up, f1), "ระบาย VWAP→L1 บน")
fill(pV, pD1, color.new(c_dn, f1), "ระบาย VWAP→L1 ล่าง")
fill(pU1, pU2, color.new(c_up, f2), "ระบาย L1→L2 บน")
fill(pD1, pD2, color.new(c_dn, f2), "ระบาย L1→L2 ล่าง")
fill(pU2, pU3, color.new(c_up, f3), "ระบาย L2→L3 บน")
fill(pD2, pD3, color.new(c_dn, f3), "ระบาย L2→L3 ล่าง")
fill(pU3, pU4, color.new(c_up, f4), "ระบาย L3→L4 บน")
fill(pD3, pD4, color.new(c_dn, f4), "ระบาย L3→L4 ล่าง")
fill(pU4, pU5, color.new(c_up, f5), "ระบาย L4→L5 บน")
fill(pD4, pD5, color.new(c_dn, f5), "ระบาย L4→L5 ล่าง")

// ── ตารางสถานะ ─────────────────────────────────────────────────────────────
sess_name = s_id == 0 ? "เอเชีย" : s_id == 1 ? "ลอนดอน" : "นิวยอร์ก"
zs = na(s_sig) or s_sig <= 0 ? float(na) : (close - s_vwap) / s_sig
m4 = mult(s_id, 4)
var table tb = table.new(position.top_right, 2, 6, border_width = 1)
if i_tbl and barstate.islast
    table.cell(tb, 0, 0, "VWAP-DL " + VER, text_color = color.white,
         bgcolor = color.new(color.black, 20), text_size = size.small)
    table.cell(tb, 1, 0, i_gauss ? "เกาส์เซียน" : i_calib, text_color = color.white,
         bgcolor = color.new(i_gauss ? color.red : color.teal, 40), text_size = size.small)
    table.cell(tb, 0, 1, "เซสชัน", text_color = color.gray, text_size = size.small)
    table.cell(tb, 1, 1, sess_name, text_color = color.white, text_size = size.small)
    table.cell(tb, 0, 2, "σ รู้ล่วงหน้า", text_color = color.gray, text_size = size.small)
    table.cell(tb, 1, 2, na(s_sig) ? "รอข้อมูล" : str.tostring(s_sig, "#.##") + " $",
         text_color = color.white, text_size = size.small)
    table.cell(tb, 0, 3, "σ สะสม (เทียบ)", text_color = color.gray, text_size = size.small)
    table.cell(tb, 1, 3, str.tostring(s_sd_live, "#.##") + " $",
         text_color = color.gray, text_size = size.small)
    table.cell(tb, 0, 4, "ราคาอยู่ที่", text_color = color.gray, text_size = size.small)
    table.cell(tb, 1, 4, na(zs) ? "—" : str.tostring(zs, "#.##") + " σ",
         text_color = na(zs) ? color.gray : math.abs(zs) >= m4 ? color.yellow : color.white,
         text_size = size.small)
    table.cell(tb, 0, 5, i_gvz ? "อัตราส่วน GVZ" : "σ วัน", text_color = color.gray, text_size = size.small)
    table.cell(tb, 1, 5, i_gvz ? str.tostring(gvz_r, "#.###") + "×" :
         (na(d_sig) ? "รอข้อมูล" : str.tostring(d_sig, "#.##") + " $"),
         text_color = i_gvz ? (gvz_r > 1.05 ? color.yellow : gvz_r < 0.95 ? color.aqua : color.white) : c_dvw,
         text_size = size.small)