Isolated Scroll Container

1. Mô tả VWAP Volume Profile Strategy

Một hồ sơ khối lượng hai chiều dựng trên đường VWAP thay vì trên giá: khối lượng của mỗi nến được gắn dấu cộng hoặc trừ tuỳ VWAP đang lên hay xuống, rồi gom lại thành biểu đồ cột nằm ngang chìa ra cả hai phía ở mép phải chart.

1.1 Concept của chỉ báo

Chỉ báo lấy ý tưởng Volume Profile quen thuộc (biểu đồ cột nằm ngang cho biết vùng giá nào hút nhiều khối lượng nhất) rồi thay đổi hai chỗ cốt lõi khiến nó trở thành một công cụ khác hẳn:

  • Thứ nhất: nó gom khối lượng theo mức VWAP, không phải theo mức GIÁ. Volume Profile thường hỏi "giá giao dịch nhiều nhất ở đâu". Chỉ báo này hỏi "đường VWAP đã nằm lâu nhất ở vùng nào". VWAP là giá trung bình có trọng số khối lượng — nó đại diện cho "mức giá vốn trung bình" mà thị trường thực sự trả trong phiên. Gom theo VWAP tức là đi tìm vùng giá mà chi phí trung bình của thị trường hay lui tới, chứ không phải vùng mà giá chỉ đi ngang qua.
  • Thứ hai: khối lượng được gắn DẤU. Mỗi nến, chỉ báo hỏi "VWAP hiện cao hơn hay thấp hơn 2 nến trước?". Cao hơn → khối lượng nến đó tính là dương; thấp hơn → tính là âm. Kết quả là mỗi vùng giá không chỉ có một con số "nhiều hay ít khối lượng", mà có một con số ròng cho biết vùng đó nghiêng về phe mua hay phe bán. Trên chart, bin dương vẽ xanh ngọc chìa sang PHẢI, bin âm vẽ cam chìa sang TRÁI — tạo thành một hồ sơ hai chiều đối xứng quanh một trục dọc.

Từ đó chỉ báo rút ra hai mức quan trọng thay vì một: +VWAP là vùng có dòng tiền ròng dương mạnh nhất (nơi phe mua tích luỹ nhiều nhất), và −VWAP là vùng có dòng tiền ròng âm mạnh nhất (nơi phe bán áp đảo nhất). Hai mức này được vẽ thành hai dải ngang kéo dài suốt cửa sổ quan sát, đóng vai trò hỗ trợ và kháng cự có cơ sở dòng tiền.

1.2 Chức năng của chỉ báo

  • Hiển thị:
    • Hồ sơ khối lượng hai chiều (ở mép phải chart): một chồng các thanh ngang, mỗi thanh ứng với một lát giá. Thanh xanh ngọc chìa sang phải = vùng có dòng tiền ròng DƯƠNG; thanh cam chìa sang trái = dòng tiền ròng ÂM. Thanh càng dài thì dòng tiền ròng càng mạnh. Độ đậm nhạt của màu cũng tỉ lệ với độ mạnh: vùng yếu gần như trong suốt, vùng mạnh nhất có màu đậm nhất.
    • Dải +VWAP: một dải ngang xanh ngọc mờ, kéo dài suốt cửa sổ quan sát, đặt tại lát giá có dòng tiền ròng dương lớn nhất. Kèm nhãn chữ căn trái dạng +VWAP: 9.771K.
    • Dải −VWAP: tương tự nhưng màu cam, đặt tại lát giá có dòng tiền ròng âm lớn nhất, nhãn dạng −VWAP: 142.375K.
    • Đường VWAP dày: một đường dày 3px bám theo giá, tự đổi màu — xanh ngọc khi VWAP đang cao hơn 5 nến trước, cam khi thấp hơn.
    • Nến đổi màu: toàn bộ nến trong cửa sổ quan sát được tô lại theo đúng màu của đường VWAP tại nến đó. Các nến nằm ngoài cửa sổ giữ nguyên màu gốc của chart.
    • Nền xanh navy: một hộp chữ nhật mờ màu xanh navy đậm phủ toàn bộ vùng quan sát (từ đáy thấp nhất tới đỉnh cao nhất, suốt chiều dài period) — giúp phân biệt rõ "vùng chỉ báo đang làm việc" với phần chart cũ hơn.
    • Cảnh báo thiếu dữ liệu: nếu mã đang xem không có dữ liệu khối lượng, một nhãn chữ rất to "No Volume Data Provided" hiện giữa chart.
  • Alert: Chỉ báo KHÔNG có lệnh alertcondition() nào — thuần tuý trực quan.

1.3 Cách dùng chỉ báo

  • Dùng dải +VWAP làm hỗ trợ, dải −VWAP làm kháng cự. Đây là cách dùng chính. Dải xanh là vùng phe mua đã tích luỹ mạnh nhất trong cửa sổ quan sát — giá hồi về đó thường gặp lực đỡ. Dải cam là vùng phe bán áp đảo nhất — giá bật lên đó thường gặp lực chặn.
  • Đọc vị trí giá hiện tại so với HAI dải để biết cục diện. Giá nằm trên cả hai dải = phe mua đang kiểm soát hoàn toàn. Giá nằm dưới cả hai = phe bán kiểm soát. Giá kẹt giữa hai dải = thị trường đang giằng co, và khoảng giữa đó chính là biên độ đi ngang có cơ sở dòng tiền — hợp cho chiến lược mua đáy bán đỉnh trong biên.
  • Nhìn hình dạng tổng thể của hồ sơ để đánh giá cán cân. Nếu phần lớn thanh chìa sang phải (xanh), dòng tiền ròng trong cửa sổ nghiêng về mua; nghiêng sang trái (cam) thì nghiêng về bán. Hồ sơ cân bằng hai bên = thị trường không có phe nào thắng rõ.
  • Dùng màu nến và màu đường VWAP làm bộ lọc hướng. Nến đang xanh ngọc = VWAP đang đi lên, ưu tiên tìm lệnh mua. Nến cam = ưu tiên lệnh bán. Đây là tín hiệu nhanh và đơn giản nhất trên chart.
  • Kết hợp hai lớp tín hiệu để lọc chất lượng. Tín hiệu mạnh nhất là khi giá chạm dải +VWAP trong lúc nến vừa chuyển sang xanh — tức vùng tích luỹ đang được kiểm chứng đúng lúc VWAP bẻ hướng lên. Chạm dải mà nến vẫn cam là tín hiệu yếu hơn nhiều.
  • Chuyển chế độ POC khi muốn chart gọn. Ô "POC" cho phép chọn hiện chỉ dải +VWAP, chỉ dải −VWAP, hoặc cả hai (mặc định). Người giao dịch một chiều có thể chỉ hiện dải mình cần.
  • Chỉnh period theo tầm nhìn. Để 250 (mặc định) cho cái nhìn trung hạn. Giảm xuống 100 → hồ sơ phản ánh dòng tiền gần đây, hai dải bám sát giá hiện tại hơn. Tăng lên 400 → hai dải ổn định và ít di chuyển hơn, hợp swing trade.

1.4 Cách hoạt động của chỉ báo

Đầu vào & vai trò

  • period (số nguyên, mặc định 250): số nến trong cửa sổ quan sát. Quyết định ba thứ cùng lúc — phạm vi giá của lưới bin (lấy đỉnh cao nhất và đáy thấp nhất trong period nến), số mẫu VWAP được đem đi gom, và chiều dài của nền navy cùng hai dải POC. Ví dụ: BTCUSDT khung 6 giờ, period 250 ≈ 62 ngày dữ liệu. Giảm xuống 100 thì lưới bin co lại theo biên độ giá 25 ngày gần nhất, hai dải POC sẽ nhảy sang vị trí khác hẳn.
  • offset (số nguyên, mặc định 10): khoảng cách tính bằng nến từ cây nến cuối cùng tới trục dọc mà hồ sơ mọc ra từ đó. Chỉ có tác dụng thẩm mỹ — đẩy hồ sơ ra xa mép phải để không che mất các nến gần nhất. Để 0 thì hồ sơ dính sát nến hiện tại.
  • bins (số nguyên, mặc định 50): số lát cắt chia đôi phạm vi giá. Tăng lên 100 → mỗi lát mỏng hơn, hồ sơ chi tiết hơn nhưng mỗi lát gom được ít mẫu hơn nên dễ lởm chởm. Giảm xuống 20 → hồ sơ thô, ít lát, mỗi lát rất dày, hai dải POC cũng dày theo. Đây là input đánh đổi giữa độ chi tiết và độ mượt.
  • poc_type1 ("POC", ô thả xuống ba lựa chọn "+VWAP" / "−VWAP" / "+/−VWAP", mặc định +/−VWAP): quyết định vẽ dải nào. Bên trong code nó được đổi thành số 1 / 2 / 3 để so sánh cho gọn. Không ảnh hưởng tới phép tính — hồ sơ vẫn được gom đầy đủ, chỉ là dải nào được vẽ ra thôi.
  • up_col (chọn màu, mặc định #42bda8 — xanh ngọc): màu cho mọi thứ thuộc phe dương — thanh bin dương, dải +VWAP, đường VWAP khi đang lên, nến khi VWAP đang lên.
  • dn_col (chọn màu, mặc định #ffb950 — cam): đối xứng hoàn toàn cho phe âm.
  • bgcol (chọn màu, mặc định rgb(5, 38, 82, 80) — xanh navy đậm, độ mờ 80): màu nền của hộp phủ vùng quan sát.

Hằng số cố định trong code (KHÔNG phải input)

  • Độ lệch 2 nến trong src > src[2]: dùng để quyết định khối lượng nến đó mang dấu cộng hay dấu trừ.
  • Độ lệch 5 nến trong vwap > vwap[5]: dùng để quyết định màu đường VWAP và màu nến. Lưu ý đây là một con số KHÁC với con số 2 ở trên — xem phần lưu ý kỹ thuật.
  • ta.highest(vol, 1000): lấy khối lượng lớn nhất của một nến trong 1000 nến gần nhất, dùng làm mẫu số chuẩn hoá.
  • Hệ số 20 trong volume_ / sum * 20: mỗi nến đóng góp tối đa ±20 đơn vị vào một lát.
  • max_bars_back = 500 và max_boxes_count = 500: trần bộ nhớ lịch sử và trần số hộp vẽ được.

Các khối logic chính

📈 Luồng 1 — Đường VWAP và màu của nó (mọi nến)

  • vwap = ta.vwap(close) — VWAP tiêu chuẩn của TradingView, neo theo phiên: cứ sang phiên mới là nó reset và tính lại từ đầu. Nghĩa là chuỗi VWAP trong 250 nến chứa vài lần "nhảy" về sát giá ở mỗi đầu phiên.
  • vwap_col = vwap > vwap[5] ? up_col : dn_col — so VWAP hiện tại với chính nó 5 nến trước. Cao hơn → xanh ngọc, thấp hơn → cam. Màu này dùng cho cả đường VWAP lẫn toàn bộ nến.
  • src = vwap — gán lại cho gọn. Đây chính là chuỗi số sẽ được đem đi gom thành hồ sơ, chứ không phải giá.

➕➖ Luồng 2 — Gắn dấu và chuẩn hoá khối lượng (hàm get_vol)

  • Kiểm tra an toàn trước: nếu tổng khối lượng cộng dồn gần như bằng 0 (mã không có dữ liệu volume, hay gặp ở một số cặp forex hoặc chỉ số), chỉ báo bắn ra một nhãn chữ cỡ size.huge ghi "No Volume Data Provided" ngay giữa chart.
  • sum = ta.highest(vol, 1000) — khối lượng lớn nhất của MỘT nến trong 1000 nến gần nhất. Đây là mốc chuẩn để quy mọi nến về cùng thang đo, giúp chỉ báo chạy được trên mọi mã dù volume tính bằng đơn vị nào.
  • volume_ = src > src[2] ? vol : -vol — bước gắn dấu, trái tim của chỉ báo. VWAP hiện cao hơn 2 nến trước → khối lượng nến này mang dấu cộng. Thấp hơn → mang dấu trừ.
  • volume_ / sum * 20 — quy về thang ±20. Ví dụ: nến lớn nhất trong 1000 nến có volume 5.000. Nến hiện tại volume 2.500 và VWAP đang lên → đóng góp 2500/5000 × 20 = +10. Nến volume 500 và VWAP đang xuống → đóng góp −500/5000 × 20 = −2.

📏 Luồng 3 — Dựng lưới lát cắt giá (hàm get_grid)

  • H = ta.highest(period) và L = ta.lowest(period) — đỉnh cao nhất và đáy thấp nhất trong period nến. Lưu ý hai hàm này mặc định dùng high và low của giá, nên lưới được dựng theo phạm vi GIÁ dù thứ đem đi gom lại là VWAP. Điều này hợp lý vì VWAP luôn nằm trong phạm vi giá.
  • step = (H − L) / bins — bề dày của mỗi lát. Ví dụ: BTCUSDT có H = 124.000 và L = 96.450 trong 250 nến → phạm vi 27.550; chia 50 lát → mỗi lát dày 551 USD.

🧮 Luồng 4 — Gom khối lượng vào từng lát (chỉ chạy tại NẾN CUỐI CÙNG)

  • Toàn bộ khối này nằm trong if barstate.islast — chỉ chạy đúng một lần, tại cây nến cuối cùng của chart. Đây là đặc điểm quan trọng nhất về mặt kỹ thuật, xem phần lưu ý.
  • Hai vòng lặp lồng nhau: vòng ngoài chạy qua từng lát i (0 đến 49), vòng trong chạy qua từng nến j trong period (0 đến 249). Tổng cộng 50 × 250 = 12.500 lượt kiểm tra.
  • Với mỗi cặp (lát, nến): nếu giá trị VWAP của nến đó rơi vào khoảng [low_ − step, high_ + step] thì cộng đóng góp của nến vào lát. Chú ý khoảng này rộng 3 lát chứ không phải 1 — mỗi mẫu VWAP được cộng vào khoảng 3 lát liền kề, tạo hiệu ứng làm mượt.
  • Có hai bộ đếm song song cho mỗi lát:
    · volume_1 — cộng dồn giá trị có dấu, đã chuẩn hoá, và bị ép về số nguyên bằng int(). Đây là con số quyết định chiều dài thanh, màu sắc, và vị trí hai dải POC.
    · volume_2 — cộng dồn khối lượng thô, không dấu. Con số này chỉ dùng để in lên nhãn của hai dải POC.

🎨 Luồng 5 — Vẽ hồ sơ hai chiều

  • int n = bar_index + offset — trục dọc mà mọi thanh mọc ra từ đó, nằm cách nến cuối 10 nến về phía phải.
  • Mỗi lát được vẽ thành một hộp từ n tới n + volume_1[i]. Vì volume_1 có dấu, đây chính là chỗ tạo ra hiệu ứng hai chiều: giá trị dương → hộp chìa sang phải; giá trị âm → hộp chìa sang trái. Chiều dài hộp tính bằng số nến, đúng bằng trị tuyệt đối của con số đó.
  • Màu nền hộp được pha bằng color.from_gradient: lát dương pha từ xanh ngọc rất mờ (ở mức 0) tới xanh ngọc đậm (ở lát dương mạnh nhất); lát âm pha từ cam đậm (ở lát âm mạnh nhất) tới cam rất mờ (ở mức 0). Nên chỉ cần nhìn độ đậm là biết lát đó mạnh cỡ nào.
  • Mảng hộp vp được khai báo bằng var nên chỉ tạo hộp một lần rồi tái sử dụng: các lần chạy sau chỉ gọi set_lefttop / set_rightbottom / set_bgcolor để cập nhật, tránh sinh ra hàng nghìn hộp mới mỗi tick.

🎯 Luồng 6 — Xác định và vẽ hai dải POC

  • Dải +VWAP: lát nào có volume_1 lớn nhất (dương mạnh nhất) sẽ được chọn. Một hộp rộng được vẽ từ bar_index − period tới n, phủ đúng dải giá của lát đó, nền màu mờ 90, viền mờ 50, kèm chữ "+VWAP: " + khối lượng thô căn trái.
  • Dải −VWAP: lát nào có volume_1 nhỏ nhất (âm mạnh nhất) — vẽ y hệt nhưng màu cam và chữ "−VWAP: ...".
  • Ô "POC" quyết định vẽ dải nào: chọn "+VWAP" chỉ vẽ dải xanh, "−VWAP" chỉ vẽ dải cam, "+/−VWAP" vẽ cả hai.
  • Hộp nền navy: vẽ cuối cùng, một hộp từ bar_index − period tới n, cao từ L tới H, không viền. Mỗi lần vẽ mới thì hộp của lần trước bị xoá đi để không chồng chất.

🕯️ Luồng 7 — Đường VWAP và màu nến trên chart

  • last_bar_index − bar_index < period — điều kiện cổng: chỉ những nến nằm trong period nến cuối cùng mới được tô màu và mới có đường VWAP. Các nến cũ hơn nhận màu na nên giữ nguyên màu gốc của chart. Đây là lý do trên chart bạn thấy phần bên trái hộp navy là nến bình thường, phần bên trong mới đổi màu.
  • plot(...) vẽ đường VWAP dày 3px, plotcandle(...) vẽ đè cả bộ nến mới (thân, viền, râu) theo màu VWAP.

Đầu ra & vai trò trong sử dụng

  • Hồ sơ hai chiều: bức tranh tổng thể về cán cân dòng tiền theo từng vùng giá — nhìn một cái là biết phe nào đang chiếm ưu thế ở đâu.
  • Dải +VWAP: vùng hỗ trợ có cơ sở dòng tiền mua, dùng làm điểm canh mua và mốc đặt Stop Loss.
  • Dải −VWAP: vùng kháng cự có cơ sở dòng tiền bán, dùng làm điểm canh bán.
  • Đường VWAP + màu nến: bộ lọc hướng nhanh, dùng để xác nhận tín hiệu từ hai dải.
💡 Lưu ý kỹ thuật quan trọng:
  • Toàn bộ hồ sơ CHỈ tồn tại tại cây nến cuối cùng — không hề có lịch sử. Khối tính toán nằm trong if barstate.islast, nghĩa là ở mọi nến quá khứ chỉ báo không tính gì cả. Bạn chỉ luôn nhìn thấy đúng một ảnh chụp tại thời điểm hiện tại; kéo chart lùi lại sẽ không thấy hồ sơ của quá khứ. Đây là điều tối quan trọng cho Phase B và Phase D: không thể backtest trực tiếp chỉ báo này, vì hai dải POC chưa từng tồn tại ở các nến trong quá khứ. Muốn chuyển thành strategy thì bắt buộc phải viết lại phần gom hồ sơ để nó chạy ở MỌI nến — và khi đó chi phí tính toán 12.500 lượt/nến sẽ trở thành vấn đề thật sự.
  • Hai con số trên hai dải KHÔNG so sánh trực tiếp được với nhau. Trên ảnh chart mẫu, dải hiện +VWAP: 9.771K còn dải kia hiện −VWAP: 142.375K — nhìn qua dễ kết luận "phe bán mạnh gấp 14 lần". Thực tế không phải vậy: vị trí hai dải được chọn bằng volume_1 (khối lượng có dấu, đã chuẩn hoá), nhưng con số in ra lại là volume_2 (khối lượng thô, KHÔNG dấu). Một lát có thể có dòng tiền ròng dương rất mạnh nhưng tổng khối lượng thô nhỏ, và ngược lại. Hãy đọc hai con số đó như "tổng khối lượng đã giao dịch tại vùng này", chứ đừng đem chúng ra so hơn kém.
  • Phép ép về số nguyên làm mất trắng đóng góp của các nến nhỏ. Dòng int(volume_[j]) cắt bỏ phần thập phân. Vì mỗi nến đóng góp tối đa ±20, một nến có khối lượng dưới 5% của nến lớn nhất trong 1000 nến sẽ cho giá trị nhỏ hơn 1 và bị ép về 0 — tức là hoàn toàn không được tính. Trên các mã có một vài cây nến volume đột biến rất lớn, phần lớn nến bình thường sẽ bị triệt tiêu và hồ sơ chỉ phản ánh một nhúm nến to. Đây có lẽ là điểm gây sai lệch lớn nhất trong toàn bộ chỉ báo.
  • Hồ sơ KHÔNG phải histogram chặt. Điều kiện nhận mẫu là [low_ − step, high_ + step], rộng gấp 3 lần một lát. Gần như mọi mẫu VWAP đều được cộng lặp vào 3 lát liền kề. Hình dạng hồ sơ vì vậy được làm mượt đáng kể và tổng khối lượng trên tất cả các lát lớn hơn khối lượng thực tế khoảng 3 lần. Đừng đọc chiều dài thanh như một tỉ lệ phần trăm tuyệt đối.
  • Hai độ lệch khác nhau cho cùng một ý "VWAP đang lên". Màu nến và màu đường dùng vwap > vwap[5] (5 nến), còn dấu của khối lượng dùng src > src[2] (2 nến). Hậu quả: một cây nến có thể hiện màu cam trong khi khối lượng của nó lại được tính là dương, hoặc ngược lại. Nếu ở Phase B bạn định dùng "màu nến" làm điều kiện vào lệnh và tưởng nó đồng nghĩa với "phía dương của hồ sơ", thì đó là hai thứ khác nhau.
  • VWAP reset mỗi phiên, tạo các cú nhảy trong chuỗi được gom. ta.vwap neo theo phiên giao dịch. Trong 250 nến sẽ có nhiều lần VWAP bị kéo giật về sát giá ở đầu phiên mới. Những cú nhảy này cũng được gom vào hồ sơ như mọi mẫu khác, và chúng không mang ý nghĩa "thị trường lui tới vùng đó" mà chỉ là hệ quả của việc reset. Trên khung thời gian nhỏ (M5, M15) số lần reset trong cửa sổ rất nhiều nên hiệu ứng này càng rõ.
  • Khi nhiều lát bằng điểm nhau, lát ở TRÊN thắng. Vòng lặp chạy từ lát thấp nhất lên cao nhất và mỗi lần gặp lát đạt max lại xoá dải cũ rồi vẽ lại. Nên nếu có 3 lát cùng đạt giá trị lớn nhất, dải POC cuối cùng sẽ nằm ở lát cao giá nhất trong 3 lát đó. Trường hợp này xảy ra khá dễ vì volume_1 là số nguyên.
  • period không nên vượt quá 500. Dòng khai báo đặt max_bars_back = 500, trong khi vòng lặp cần truy cập tới src[period − 1]. Đặt period lớn hơn 500 sẽ có nguy cơ gặp lỗi "historical offset beyond the allowed limit". Ngoài ra ta.highest(vol, 1000) nhìn xa tới 1000 nến — vượt cả con số 500 khai báo.
  • Vài đoạn code thừa hoặc đặt tên gây hiểu nhầm. (a) Biến sum thực chất là giá trị lớn nhất, không phải tổng. (b) Hàm get_vol(vwap) nhận một tham số tên vwap nhưng bên trong không hề dùng tới nó — nó đọc thẳng biến toàn cục src. (c) Dòng barcolor(vwap_col, display = display.none) bị ẩn hoàn toàn nên không vẽ gì cả; việc tô nến do plotcandle đảm nhiệm. (d) Các tham số force_overlay đều thừa vì chỉ báo vốn đã khai báo overlay = true. Những chỗ này không gây lỗi nhưng dễ làm người đọc code hiểu sai ý đồ.
  • Ba ô nhập đầu tiên không có tên. period, offset và bins đều được khai báo kiểu input.int(250) — không truyền tham số tiêu đề. Trong bảng Settings chúng hiện ra là ba ô số trống không nhãn, xếp theo đúng thứ tự trên. Tương tự, ba ô màu nằm chung một hàng chỉ có duy nhất chữ "+/−" ở đầu hàng: ô thứ nhất là màu dương, ô thứ hai màu âm, ô thứ ba màu nền.
Zoom/Pan Layered Image
Background Overlay
− +

Chỉ báo trên vừa hoá thành BOT TRADE — chỉ 1 click AI

📊Chỉ báo gốc
→
🤖AI convert 1-click
→
⚙️Bot tự trade 24/7