1. Mô tả Market Structure Confluence Strategy
Chỉ báo tìm các đỉnh/đáy swing, đánh dấu mỗi lần giá phá vỡ cấu trúc (BOS) hoặc đổi chiều cấu trúc (CHoCH), tô màu nến theo xu hướng hiện hành, rồi vẽ thêm một dải biến động (WMA ± ATR) chỉ ở phía thuận xu hướng để bắt những lần giá quay lại chạm dải.
1.1 Concept của chỉ báo
Chỉ báo ghép hai "bộ máy" độc lập lại với nhau (đó là ý nghĩa của chữ Confluence — hợp lưu) và trả lời hai câu hỏi liên tiếp: "Xu hướng hiện tại đang nghiêng về phe nào?" rồi "Khi giá quay lại chạm dải biến động cùng phía với xu hướng đó, có phải là điểm vào lệnh thuận xu hướng không?"
- Bộ máy 1 — Cấu trúc thị trường (Market Structure): xu hướng được quyết định bởi cú phá vỡ gần nhất. Chỉ báo tìm các đỉnh swing và đáy swing (điểm mà giá đảo chiều rõ rệt: một đỉnh cao hơn hẳn 10 nến bên trái và 10 nến bên phải thì là đỉnh swing). Khi giá vượt lên trên đỉnh swing gần nhất → thị trường "phá vỡ cấu trúc" đi lên. Khi giá thủng xuống dưới đáy swing gần nhất → phá vỡ cấu trúc đi xuống. Hướng của cú phá vỡ gần nhất chính là xu hướng hiện hành.
- BOS và CHoCH — hai tên gọi cho hai loại phá vỡ. BOS (Break of Structure — phá vỡ cấu trúc) là cú phá vỡ cùng hướng với xu hướng đang có: đang tăng mà tiếp tục phá đỉnh → xu hướng được củng cố. CHoCH (Change of Character — đổi tính chất) là cú phá vỡ ngược hướng với xu hướng đang có: đang tăng mà lại thủng đáy swing → dấu hiệu đầu tiên cho thấy phe mua yếu đi và xu hướng có thể đã đổi chiều.
- Bộ máy 2 — Dải biến động (Volatility Band): một đường trung bình cộng/trừ độ rộng dao động. Chỉ báo lấy đường trung bình WMA 100 nến của giá đóng cửa (trung bình có trọng số: nến càng mới càng được tính nặng), rồi cộng và trừ 2 lần "độ rộng dao động trung bình" (ATR đã làm mượt) để ra một dải trên và một dải dưới. Nhưng chỉ một dải được vẽ ra tại mỗi thời điểm, chọn theo xu hướng ở Bộ máy 1: xu hướng tăng → vẽ dải dưới (đóng vai trò vùng hỗ trợ động); xu hướng giảm → vẽ dải trên (vùng kháng cự động).
- Hợp lưu — nơi hai bộ máy gặp nhau. Mũi tên ▲ / ▼ chỉ xuất hiện khi giá chạm vào dải đồng thời xu hướng đang cùng phía với dải đó. Ý tưởng: trong xu hướng tăng, giá hay hồi về hỗ trợ rồi đi tiếp; chỉ báo đánh dấu chính những lần hồi về đó.
Niềm tin nền tảng: thị trường đi theo từng nhịp đỉnh đáy, và cú phá vỡ đỉnh/đáy gần nhất là bằng chứng rõ nhất cho phe nào đang nắm quyền. Khi xu hướng đã rõ, những lần giá lùi về một đường trung bình động cộng/trừ biên độ dao động là cơ hội vào lệnh thuận chiều có rủi ro nhỏ hơn việc đuổi theo giá.
1.2 Chức năng của chỉ báo
-
Hiển thị:
- Nhãn swing HH / LH / HL / LL: chữ đặt ngay tại đỉnh hoặc đáy swing, mờ 50% để không rối chart. HH (Higher High — đỉnh cao hơn đỉnh trước) và HL (Higher Low — đáy cao hơn đáy trước) màu xanh ngọc; LH (Lower High — đỉnh thấp hơn đỉnh trước) và LL (Lower Low — đáy thấp hơn đáy trước) màu đỏ. Nhãn đỉnh nằm phía trên điểm, nhãn đáy nằm phía dưới. Tắt được bằng ô "Show Swing Labels".
- Đường BOS / CHoCH: một đường ngang, nét mảnh (độ dày 1), kéo từ đúng cây nến tạo ra đỉnh/đáy swing đến cây nến mà giá phá vỡ nó. Chữ "BOS" hoặc "CHoCH" nằm ở giữa đường. Phá lên → xanh ngọc, chữ nằm phía trên đường. Phá xuống → đỏ, chữ nằm phía dưới đường. Kiểu nét (liền / đứt / chấm) chọn được.
- Nến đổi màu theo xu hướng: mọi nến trên chart được tô lại — xanh ngọc khi xu hướng hiện hành là tăng, đỏ khi là giảm. Màu chỉ phụ thuộc cú phá vỡ gần nhất, không phụ thuộc nến đó tăng hay giảm.
- Dải biến động (Band): một đường dày (độ dày 3), chỉ hiện một phía tại mỗi thời điểm: dải dưới xanh ngọc khi xu hướng tăng, dải trên đỏ khi xu hướng giảm. Đường bị ngắt (không nối liền) mỗi khi xu hướng đổi phía.
- Mũi tên tín hiệu ▲ / ▼ (Bullish / Bearish Signal): ▲ xanh ngọc nằm dưới dải dưới (cách đúng 1 ATR), ▼ đỏ nằm trên dải trên. Xuất hiện khi thân-và-râu của một cây nến cắt ngang dải (chi tiết ở 1.4).
- Điểm ◉ đổi xu hướng (Trend Change): một chấm tròn đặt đúng tại vị trí dải ở cây nến mà xu hướng đổi (hoặc xác lập lần đầu). ◉ xanh ngọc nằm trên đường dải dưới, ◉ đỏ nằm trên đường dải trên.
-
Alert: có 12 lệnh alertcondition() để bạn chọn khi tạo cảnh báo trên TradingView:
- Bullish CHoCH / Bullish BOS / Bearish CHoCH / Bearish BOS — 4 cảnh báo cho các cú phá vỡ. Cảnh báo: hai alert "CHoCH" không bao giờ phát tín hiệu và hai alert "BOS" phát cho mọi cú phá vỡ (lỗi trong code, xem ô lưu ý cuối mục).
- HH Detected / LH Detected / HL Detected / LL Detected — mỗi khi một đỉnh/đáy swing mới được xác nhận và xếp loại tương ứng (xác nhận chậm 10 nến so với lúc đỉnh/đáy thực sự hình thành).
- Bullish Arrow Signal / Bearish Arrow Signal — khi mũi tên ▲ / ▼ xuất hiện (nội dung thông báo ghi "Rejection Signal").
- Bullish Trend Change / Bearish Trend Change — khi điểm ◉ xuất hiện, tức khi xu hướng đổi chiều (hoặc cú phá vỡ đầu tiên trên chart). Đây mới là cặp alert báo đúng CHoCH.
- Tất cả 12 alert đều đi qua ô "Wait for Bar Close (alerts)" (bật mặc định): bật thì chỉ phát sau khi nến đã đóng.
1.3 Cách dùng chỉ báo
- Dùng màu nến làm bộ lọc hướng giao dịch. Nến xanh ngọc → chỉ tìm lệnh mua. Nến đỏ → chỉ tìm lệnh bán. Màu nến cho bạn biết "đang ở phe nào" chứ không cho biết nên vào lệnh ở đâu.
- Coi CHoCH là cảnh báo sớm đổi xu hướng, còn BOS là xác nhận tiếp diễn. Chữ CHoCH xuất hiện = cú phá vỡ đầu tiên ngược chiều xu hướng cũ: nên ngừng nhồi thêm lệnh theo hướng cũ, cân nhắc chốt lời một phần hoặc dời Stop Loss lên sát. Chữ BOS = xu hướng vẫn khoẻ, tiếp tục giữ lệnh hoặc tìm điểm vào mới theo hướng đó.
- Vào lệnh thuận xu hướng tại mũi tên. Khi nến xanh ngọc và xuất hiện ▲ → giá vừa hồi về chạm dải dưới trong xu hướng tăng, ứng viên cho lệnh mua. Khi nến đỏ và xuất hiện ▼ → giá vừa hồi lên chạm dải trên trong xu hướng giảm, ứng viên cho lệnh bán. Đây chính là phần "hợp lưu" của chỉ báo.
- Chỉ coi mũi tên là điểm để chú ý, không phải lệnh tự động. Điều kiện của mũi tên chỉ yêu cầu nến cắt qua dải, không yêu cầu nến đóng cửa quay lại đúng phía (xem ô lưu ý). Nên chờ thêm xác nhận: nến đóng cửa lại phía thuận xu hướng, hoặc thêm một bộ lọc riêng.
- Dùng đường BOS/CHoCH vừa bị phá làm mốc Stop Loss. Sau cú phá lên, mức đỉnh vừa bị phá thường trở thành hỗ trợ, đáy swing gần nhất là mốc kỹ thuật tự nhiên để đặt SL. Với lệnh bán làm ngược lại. Dải biến động cũng có thể làm mốc SL động (đặt ngoài dải một chút).
- Đọc chuỗi HH/HL hoặc LH/LL để thấy "sức khoẻ" xu hướng. Tăng khoẻ thường có HH và HL nối nhau. Nếu xuất hiện LH khi nến còn xanh, đỉnh mới không vượt nổi đỉnh cũ — thường là báo hiệu động lượng đang yếu trước khi có CHoCH.
- Chỉnh "Time-Horizon" theo khung thời gian và phong cách. Để 10 (mặc định) cho cấu trúc cân bằng. Giảm xuống 4–6 → nhiều swing nhỏ, BOS/CHoCH ra dày, hợp scalping nhưng nhiễu và dễ đổi màu liên tục. Tăng lên 20–30 → chỉ còn các swing lớn, BOS/CHoCH ít nhưng đáng tin hơn, hợp swing trade nhưng báo trễ hơn nhiều.
- Chỉnh "Basis Length" và "Volatility Multiplier" để dải ôm giá chặt hơn hoặc xa hơn. Hạ Basis Length xuống 50 → đường trung bình bám giá sát, dải gần giá hơn, mũi tên ra dày. Tăng lên 200 → dải xa, chỉ chạm sau các nhịp hồi sâu.
1.4 Cách hoạt động của chỉ báo
Đầu vào & vai trò
Nhóm "Market Structure" — chỉ ảnh hưởng tới cấu trúc, xu hướng, đường BOS/CHoCH và màu nến
- swingSize ("Time-Horizon", số nguyên, mặc định 10, tối thiểu 2): số nến nhìn sang mỗi bên để xác định một đỉnh/đáy swing. Một nến chỉ được công nhận là đỉnh swing khi đỉnh của nó cao hơn 10 nến bên trái và 10 nến bên phải. Hệ quả quan trọng: phải đợi đủ 10 nến sau đó mới biết có đỉnh hay không, nên mọi swing đều được xác nhận trễ 10 nến (nhưng một khi đã xác nhận thì không thay đổi nữa). Ví dụ trên M15: 10 nến = 2,5 giờ. Để 10 → một swing cần cửa sổ 21 nến, báo trễ 2,5 giờ. Giảm xuống 5 → báo trễ 1,25 giờ nhưng bắt cả các nhịp nhỏ, cấu trúc đổi hướng liên tục. Tăng lên 20 → báo trễ 5 giờ, chỉ bắt các đỉnh/đáy lớn. Nếu thiếu input này (đặt thấp nhất = 2) mọi nhịp lắc nhỏ đều thành swing và cấu trúc gần như vô nghĩa.
- bosConfType ("BOS Confirmation", ô chọn thả xuống, hai giá trị "Candle Close" / "Wicks", mặc định Candle Close): quyết định phải dùng cái gì của nến để tính là "phá vỡ". Candle Close → giá đóng cửa phải vượt qua mức. Wicks → chỉ cần râu nến (đỉnh/đáy) chạm qua mức là tính. Ví dụ: đỉnh swing 2650, nến có đỉnh 2651 nhưng đóng cửa 2648. Chế độ Wicks → tính là BOS ngay. Chế độ Candle Close → chưa tính gì, đỉnh swing 2650 vẫn còn nguyên hiệu lực chờ phá. Wicks nhạy hơn nhưng dễ dính các cú "quét râu" giả.
- bosStyleIn ("BOS/CHoCH Line Style", thả xuống: "Solid" / "Dashed" / "Dotted", mặc định Solid): kiểu nét của đường BOS/CHoCH — liền, đứt hoặc chấm. Chỉ đổi hình dạng đường, không ảnh hưởng logic.
- showCHoCH ("Show CHoCH", ô tick, mặc định bật): bật → cú phá vỡ ngược xu hướng được ghi chữ "CHoCH". Tắt → mọi cú phá vỡ đều ghi chữ "BOS". Chỉ đổi nội dung chữ trên chart. Xu hướng, màu nến, điểm ◉ và các alert vẫn tính CHoCH như bình thường.
- showSwing ("Show Swing Labels", ô tick, mặc định bật): bật/tắt các nhãn HH/LH/HL/LL. Chỉ ảnh hưởng hiển thị. Việc phân loại swing vẫn chạy ngầm nên 4 alert HH/LH/HL/LL vẫn hoạt động khi tắt nhãn.
Nhóm "Band Settings" — chỉ ảnh hưởng tới dải, mũi tên và vị trí điểm ◉, không đụng tới cấu trúc và xu hướng
- basisLength ("Basis Length", số nguyên, mặc định 100, tối thiểu 1): số nến của đường trung bình WMA làm "tâm" của dải. Số càng lớn, tâm càng chậm và càng cách xa giá khi giá chạy mạnh. Ví dụ: XAUUSD đang chạy lên, WMA 100 có thể đang ở 2640 trong khi giá ở 2680; hạ xuống 50 thì tâm có thể ở 2660, bám sát giá hơn.
- atrLength ("ATR Length", số nguyên, mặc định 14): số nến để tính ATR (Average True Range — biên độ dao động trung bình của một nến, gồm cả khoảng nhảy giá giữa hai nến). Input này còn quyết định khoảng cách của mũi tên so với dải (mũi tên nằm cách dải đúng 1 ATR). Ví dụ: XAUUSD M15, ATR 14 thường khoảng 4–6 USD.
- atrSmooth ("ATR Smoothing", số nguyên, mặc định 21): làm mượt ATR bằng trung bình đơn giản (SMA) 21 nến, để độ rộng dải không nhảy lên xuống theo từng nến. Tăng lên → độ rộng dải ổn định hơn nhưng phản ứng chậm khi thị trường bất chợt giãn biên độ.
- volMult ("Volatility Multiplier", số thập phân, mặc định 2.0, bước 0.1, tối thiểu 0.1): hệ số nhân với ATR đã làm mượt để ra độ rộng nửa dải. Ví dụ: WMA = 2640, ATR đã làm mượt = 4 → dải trên = 2640 + 2×4 = 2648, dải dưới = 2640 − 2×4 = 2632. Đổi hệ số thành 1.0 → dải thu hẹp còn 2644 / 2636, giá chạm dải thường xuyên hơn; đổi thành 3.0 → 2652 / 2628, giá hiếm khi chạm.
Nhóm "Appearance" và "⚠️ Alerts"
- colBull ("Bull Color", chọn màu, mặc định #00FFBB — xanh ngọc sáng) và colBear ("Bear Color", chọn màu, mặc định #FF1100 — đỏ tươi): hai ô màu nằm cạnh nhau trên cùng một dòng (inline = "msc"). Khác với nhiều chỉ báo khác, hai màu này điều khiển TOÀN BỘ phần hiển thị: nến, đường BOS/CHoCH, chữ BOS/CHoCH, nhãn swing (mờ 50%), dải, mũi tên và điểm ◉.
- waitClose ("Wait for Bar Close (alerts)", ô tick, mặc định bật): chỉ ảnh hưởng 12 alert, không đụng tới hình vẽ. Bật → alert chỉ phát khi nến đã đóng hẳn (tránh báo giả do giá còn nhảy trong nến). Tắt → alert phát ngay khi điều kiện đúng trong lúc nến đang chạy.
Hằng số cố định trong code (KHÔNG phải input)
- enMS = true: công tắc "bật cấu trúc thị trường" được khoá cứng ở bật. Chỉ là dấu vết của một bản code cũ, không có tác dụng.
- bosWidth = 1: độ dày đường BOS/CHoCH. Độ mờ cố định: nhãn swing mờ 50%, màu nến mờ 30%.
- Hệ số 1× ATR của khoảng cách mũi tên (arrowOffset = volatility * 1) và độ dày 3 của đường dải: sửa code mới đổi được.
- max_lines_count = 500 và max_labels_count = 500: trần số đường/nhãn tồn tại cùng lúc; max_bars_back = 5000: số nến tối đa chỉ báo được nhìn ngược lại. Vượt trần thì TradingView tự xoá các nét cũ nhất. Lưu ý: nhãn swing (HH/LH/HL/LL) và chữ BOS/CHoCH dùng chung trần 500 nhãn này.
Các khối logic chính
📍 Luồng 1 — Tìm đỉnh/đáy swing (mọi nến)
- pivHi = ta.pivothigh(high, swingSize, swingSize) — hàm có sẵn của Pine: tại mỗi nến, nhìn lại nến cách đây swingSize nến và hỏi "đỉnh nến đó có cao hơn cả 10 nến bên trái lẫn 10 nến bên phải không?". Nếu có → trả về giá đỉnh đó; nếu không → trả về na (nghĩa là "không có giá trị", ô trống).
- pivLo = ta.pivotlow(low, swingSize, swingSize) — đối xứng cho đáy swing.
- Vì phải có đủ 10 nến bên phải, swing luôn được phát hiện trễ 10 nến. Nhãn và đường vẽ ngược về nến thật của đỉnh/đáy bằng bar_index − swingSize, nên bạn thấy nhãn nằm đúng chỗ nhưng nó chỉ hiện ra 10 nến sau đó.
- Ví dụ: nến số 100 có đỉnh 2650, và 10 nến trước lẫn 10 nến sau nó đều có đỉnh thấp hơn. Tại nến số 110, pivHi = 2650. Nhãn HH/LH được gắn vào nến số 100, nhưng chỉ xuất hiện khi chart chạy tới nến 110. Một đỉnh và một đáy có thể được xác nhận trên cùng một nến.
🏷️ Luồng 2 — Xếp loại HH / LH / HL / LL và ghi nhớ mức cần phá (khi vừa có swing mới)
- Chỉ báo giữ trong "trí nhớ" (biến khai báo bằng từ khoá var — nghĩa là biến được nhớ qua các nến, không tính lại từ đầu ở mỗi nến): prevHigh / prevLow là giá của đỉnh / đáy swing gần nhất, prevHighIdx / prevLowIdx là số thứ tự nến của chúng, highActive / lowActive cho biết mức đó còn "chưa bị phá" hay không.
- Khi có đỉnh swing mới: hh := na(prevHigh) or pivHi >= prevHigh. Đỉnh mới cao hơn hoặc bằng đỉnh swing trước → HH. Thấp hơn → LH. Đỉnh swing đầu tiên của chart luôn là HH (chưa có gì để so). Sau đó ghi đè prevHigh := pivHi, prevHighIdx := bar_index − swingSize và bật highActive := true.
- Với đáy: hl := na(prevLow) or pivLo >= prevLow. Đáy mới cao hơn hoặc bằng đáy trước → HL, thấp hơn → LL. Cũng ghi đè prevLow, prevLowIdx và bật lowActive.
- Ví dụ: đỉnh swing trước 2650. Đỉnh mới 2658 → HH. Đỉnh mới 2645 → LH. Đỉnh mới đúng bằng 2650 → vẫn tính HH (vì so sánh dùng "lớn hơn hoặc bằng").
- Hai điểm cần nhớ: (1) mức cần phá luôn là đỉnh/đáy swing MỚI NHẤT, kể cả khi nó là LH hay HL thấp hơn mức cũ — các đỉnh/đáy cũ chưa bị phá bị quên hẳn khi có swing mới. (2) HH/LH/HL/LL chỉ là nhãn và alert, không dùng để quyết định xu hướng; xu hướng chỉ do cú phá vỡ ở Luồng 3–4 quyết định.
💥 Luồng 3 — Phát hiện phá vỡ (mọi nến)
- highSrc / lowSrc là "giá dùng để kiểm tra phá vỡ": nếu bosConfType = "Candle Close" thì cả hai là close; nếu "Wicks" thì highSrc = high và lowSrc = low.
- Phá lên: highActive and highSrc > prevHigh → highBroken := true và highActive := false. Phá xuống: lowActive and lowSrc < prevLow → lowBroken := true và lowActive := false.
- Mỗi mức chỉ bị phá một lần. Ngay khi bị phá, mức bị "tắt" (Active := false) và chỉ được bật lại khi có một đỉnh/đáy swing mới thay thế. Nhờ vậy giá cứ nằm trên mức đã phá cũng không sinh thêm BOS.
- Không bỏ sót phá vỡ nào trong thời gian chờ xác nhận: vì định nghĩa swing là điểm cao nhất trong 10 nến bên phải, giá không thể vượt nó trong khoảng đó; nến sớm nhất có thể phá là nến ngay sau nến xác nhận.
- Ví dụ: prevHigh = 2650, đang ở chế độ Candle Close. Nến 125 đóng cửa 2652 → 2652 > 2650 → highBroken = true. Giữa chừng nến 120 có râu chạm 2655 nhưng đóng cửa 2648 → chưa tính, vì chế độ này chỉ nhìn giá đóng cửa.
🧭 Luồng 4 — Cập nhật xu hướng và phân biệt BOS / CHoCH (chỉ tại nến có phá vỡ)
- prevBreakDir là biến nhớ xu hướng hiện hành: 1 = tăng, −1 = giảm, 0 = chưa có cú phá vỡ nào trên chart. lastBreakDir giữ xu hướng ngay trước cú phá vỡ này.
- Khi highBroken: lastBreakDir := prevBreakDir (lưu xu hướng cũ), rồi prevBreakDir := 1 (xu hướng mới là tăng). Chữ trên chart: nếu xu hướng cũ là giảm (prevBreakDir == −1, đo trước khi cập nhật) và ô "Show CHoCH" đang bật → ghi "CHoCH", còn lại ghi "BOS".
- bullishChange := lastBreakDir == −1 or lastBreakDir == 0 — bật khi xu hướng cũ là giảm hoặc chưa có. Nghĩa là điểm ◉ (và alert "Bullish Trend Change") cũng bật ở cú phá vỡ đầu tiên trên chart, dù chữ ghi trên chart lúc đó vẫn là "BOS" (vì chưa có xu hướng cũ để ngược lại).
- Khi lowBroken: đối xứng hoàn toàn. lastBreakDir := prevBreakDir, prevBreakDir := −1; chữ "CHoCH" nếu xu hướng cũ là tăng; bearishChange := lastBreakDir == 1 or lastBreakDir == 0.
- Ví dụ chuỗi sự kiện: (1) Phá lên lần đầu → chữ "BOS", ◉ xanh, xu hướng = tăng. (2) Phá lên tiếp → chữ "BOS", không có ◉ (xu hướng tăng được củng cố). (3) Giá đóng cửa thủng đáy swing → chữ "CHoCH" đỏ, ◉ đỏ, xu hướng = giảm, toàn bộ nến sang đỏ. (4) Thủng thêm một đáy nữa → chữ "BOS" đỏ, không có ◉. (5) Phá lên một đỉnh swing → chữ "CHoCH" xanh, ◉ xanh, nến sang xanh.
- Điều quan trọng cần hiểu: xu hướng của chỉ báo chỉ đổi khi có cú phá vỡ ngược chiều. Nó có thể giữ nguyên hướng rất lâu dù giá đã đi ngang hoặc đi lệch nhiều.
✏️ Luồng 5 — Vẽ đường, chữ BOS/CHoCH, nhãn swing và tô màu nến
- Đường BOS/CHoCH: tại nến phá vỡ, line.new(prevHighIdx, prevHigh, bar_index, prevHigh, ...) vẽ đường ngang từ nến tạo đỉnh/đáy swing đến nến phá vỡ, ở đúng độ cao mức bị phá. Màu xanh ngọc khi phá lên, đỏ khi phá xuống, kiểu nét theo bosStyleIn, độ dày bosWidth = 1.
- Chữ trên đường: label.new đặt ở nến chính giữa đoạn đường (math.floor làm tròn xuống), nền trong suốt, chữ cỡ nhỏ. Phá lên → chữ đặt phía trên đường; phá xuống → chữ đặt phía dưới đường.
- Nhãn swing: khi showSwing bật, mỗi hh / lh / hl / ll vẽ một nhãn tại nến bar_index − swingSize (đúng nến của đỉnh/đáy), chữ mờ 50%, nền trong suốt. Đỉnh dùng nhãn hướng xuống (nằm phía trên điểm), đáy dùng nhãn hướng lên (nằm phía dưới điểm).
- Tô màu nến: barcolor(prevBreakDir == −1 ? đỏ mờ 30% : xanh mờ 30%). Chú ý: mọi trường hợp không phải "giảm" đều tô xanh, kể cả khi prevBreakDir = 0 (chưa có cú phá vỡ nào). Dòng này chạy sau khi xu hướng đã được cập nhật ở Luồng 4, nên nến phá vỡ đổi màu ngay tại chính nến đó.
📊 Luồng 6 — Dải biến động (mọi nến)
- volatility = ta.atr(atrLength) — ATR 14 nến, biên độ dao động trung bình của một nến.
- svol = ta.sma(volatility, atrSmooth) — lấy trung bình 21 giá trị ATR gần nhất để làm mượt.
- basis = ta.wma(close, basisLength) — trung bình có trọng số 100 nến của giá đóng cửa: nến mới nhất nặng nhất, nến xa dần nhẹ dần → bám giá sát hơn trung bình thường.
- upper = basis + volMult * svol và lower = basis − volMult * svol. Ví dụ: basis 2640, svol 4, volMult 2 → upper 2648, lower 2632.
- Chỉ vẽ một dải: plot(prevBreakDir == 1 ? lower : na, ...) vẽ dải dưới (xanh ngọc) khi xu hướng tăng; plot(prevBreakDir == −1 ? upper : na, ...) vẽ dải trên (đỏ) khi xu hướng giảm; kiểu plot.style_linebr cho phép đường bị ngắt khi giá trị là na. Khi prevBreakDir = 0 thì không vẽ gì cả.
- Hai điểm dễ gây hiểu nhầm: (1) Dải không phải đường dừng lỗ bám đuôi: nó chỉ là WMA ± hằng số nên có thể đi lên lẫn đi xuống tự do, và không đảm bảo luôn nằm đúng phía của giá (ví dụ ngay sau CHoCH tăng, WMA 100 vẫn còn nằm cao do quán tính giảm cũ, dải dưới có thể còn nằm TRÊN giá). (2) Hai dòng plot nằm ở đầu code, chạy trước lúc prevBreakDir được cập nhật ở Luồng 4, nên chúng đọc xu hướng của nến trước. Kết quả: dải chỉ bắt đầu hiện từ nến KẾ TIẾP sau cú phá vỡ.
🎯 Luồng 7 — Mũi tên ▲ / ▼ và điểm ◉ (mọi nến)
- bullishArrow = prevBreakDir == 1 and low < lower and high > lower: đang là xu hướng tăng và đáy nến thấp hơn dải dưới và đỉnh nến cao hơn dải dưới. Nghĩa là phạm vi từ đáy đến đỉnh của nến cắt ngang đường dải dưới.
- bearishArrow = prevBreakDir == −1 and low < upper and high > upper: đối xứng cho xu hướng giảm với dải trên.
- Vị trí vẽ: ▲ ở lower − arrowOffset, ▼ ở upper + arrowOffset, trong đó arrowOffset = volatility (1 ATR). Mũi tên nằm ngoài dải, cách 1 ATR, để không đè lên nến.
- Điểm ◉: plotchar(bullishChange ? lower : na, ...) đặt chấm tròn ở giá trị dải dưới tại nến đổi xu hướng; bearishChange thì đặt ở dải trên. Vì chấm đặt theo dải chứ không đặt theo giá, nó có thể nằm xa thân nến nếu dải đang cách xa giá.
- Ví dụ: xu hướng tăng, dải dưới = 2632, ATR = 5. Nến có đáy 2630, đỉnh 2636 → đáy < 2632 < đỉnh → ▲ xuất hiện tại 2632 − 5 = 2627. Nến khác có đáy 2634 (không chạm dải) → không có mũi tên. Một nến khác có đỉnh 2631 (nằm hẳn dưới dải) → cũng không có mũi tên.
- Vì Luồng 6 đọc xu hướng trễ 1 nến, mũi tên không bao giờ xuất hiện ngay tại nến phá vỡ; sớm nhất là nến kế tiếp.
🔔 Luồng 8 — Alert (mọi nến)
- barConfirmed = not waitClose or barstate.isconfirmed — nếu tắt "Wait for Bar Close" thì luôn đúng; nếu bật thì chỉ đúng khi nến đã đóng. Mỗi alert là điều kiện riêng AND barConfirmed.
- 4 alert BOS/CHoCH dùng highBroken / lowBroken kết hợp với prevBreakDir (xem lỗi ở ô lưu ý). 4 alert swing dùng thẳng hh / lh / hl / ll. 2 alert mũi tên dùng bullishArrow / bearishArrow. 2 alert Trend Change dùng bullishChange / bearishChange.
Đầu ra & vai trò trong sử dụng
- Màu nến: bộ lọc hướng giao dịch theo xu hướng hiện hành. Nến đổi màu đúng tại cây nến phá vỡ.
- Đường + chữ BOS / CHoCH: cho biết cú phá vỡ vừa xảy ra là tiếp diễn (BOS) hay đảo chiều sớm (CHoCH), và mức giá nào vừa bị phá — dùng làm mốc SL hoặc mốc quan sát.
- Nhãn HH / LH / HL / LL: bối cảnh cấu trúc, cho biết các nhịp đỉnh đáy đang nâng lên hay hạ xuống. Hiện chậm 10 nến.
- Dải biến động: vùng hỗ trợ/kháng cự động thuận xu hướng (đường dày, một phía), dùng để tìm điểm hồi quay lại.
- Mũi tên ▲ / ▼: điểm chú ý để vào lệnh thuận xu hướng khi giá chạm lại dải. Cần xác nhận thêm.
- Điểm ◉: đánh dấu cây nến xu hướng đổi chiều (hoặc xác lập lần đầu).
- 12 alert: tự động hoá việc theo dõi; dùng cặp Trend Change khi muốn báo CHoCH đúng nghĩa.
- LỖI trong code: hai alert "Bullish CHoCH" và "Bearish CHoCH" không bao giờ phát, còn hai alert "BOS" phát cho TẤT CẢ cú phá vỡ. Các dòng alertcondition nằm sau khối cập nhật xu hướng, lúc đó prevBreakDir đã bị đổi sang hướng mới. Ví dụ: tại cú phá lên, điều kiện "Bullish CHoCH" là highBroken and prevBreakDir == −1, nhưng prevBreakDir vừa được gán thành 1 nên điều kiện luôn sai. Ngược lại điều kiện "Bullish BOS" prevBreakDir != −1 luôn đúng. Kết quả: alert "BOS" chung cả BOS lẫn CHoCH, alert "CHoCH" im lặng. Cách khắc phục: dùng cặp Bullish Trend Change / Bearish Trend Change để bắt CHoCH (cặp này tính đúng, nhưng cũng bật ở cú phá vỡ đầu tiên trên chart).
- Dải, mũi tên đọc xu hướng trễ 1 nến. Do hai dòng vẽ dải và dòng tính mũi tên nằm trước dòng cập nhật prevBreakDir, chúng dùng giá trị của nến trước. Nến phá vỡ tự nó đã đổi màu và có ◉, nhưng đường dải mới chỉ bắt đầu từ nến kế tiếp, và nến phá vỡ không thể có mũi tên. Điểm ◉ đặt tại giá trị dải ở nến phá vỡ, trong khi đường dải mới hiện sau đó 1 nến.
- Mũi tên không phải "xác nhận bật lại" thực sự. Chỉ báo gọi nó là "Rejection" nhưng điều kiện chỉ cần phạm vi nến cắt qua dải, không kiểm tra giá đóng cửa có quay lại đúng phía hay không. Một nến xuyên thẳng qua dải rồi đóng cửa ở phía bên kia vẫn có mũi tên. Mũi tên cũng có thể ra nhiều nến liên tiếp khi giá đi dọc theo dải.
- Mũi tên có thể nhấp nháy trong phiên (repaint nhẹ). Điều kiện dùng high và low của nến đang chạy, mà hai giá trị này còn thay đổi cho tới lúc nến đóng. Một mũi tên có thể hiện rồi biến mất vài lần. Tương tự, ở chế độ "Candle Close", nến phá vỡ đang chạy có thể nhấp nháy khi giá đóng cửa tạm thời vượt/thụt qua mức. Chỉ nên tin tín hiệu sau khi nến đóng.
- Dải không đảm bảo nằm đúng phía của giá. Vì dải là WMA 100 nến ± hằng số, ngay sau một CHoCH (khi xu hướng vừa đảo chiều), WMA vẫn còn mang quán tính cũ nên dải dưới có thể nằm trên giá hiện tại (hoặc dải trên nằm dưới giá). Lúc đó mũi tên ▲ có thể xuất hiện khi giá đi lên xuyên qua dải dưới thay vì bật lên từ trên.
- Các nến đầu chart không có ý nghĩa. Cần ít nhất 21 nến cho swing đầu tiên và thêm thời gian cho cú phá vỡ đầu tiên; cần 100 nến cho WMA. Trước cú phá vỡ đầu tiên, prevBreakDir = 0 → toàn bộ nến hiện màu xanh ngọc dù giá đi lên hay xuống, và chưa có dải. Đừng đọc đoạn đó như tín hiệu tăng.
- Chỉ báo chỉ nhớ đúng một đỉnh và một đáy swing. Mỗi swing mới ghi đè swing cũ ngay cả khi swing cũ chưa bị phá. Nên một cú phá "đỉnh lớn" phía xa sẽ không bao giờ được ghi nhận nếu sau đó đã có một đỉnh nhỏ hơn thay thế. Cấu trúc ở đây là cấu trúc "nhịp ngắn nhất" chứ không phải cấu trúc lớn.
- Nhãn swing và alert swing trễ 10 nến. Nhãn hiện đúng nến của đỉnh/đáy nhưng chỉ xuất hiện sau khi đủ 10 nến, nên không dùng để vào lệnh sớm. Một khi đã hiện thì không thay đổi (không repaint).
- Cả hai mức có thể bị phá cùng một nến (nến rất lớn ở chế độ Wicks, hoặc khi mức đỉnh và mức đáy đang đảo ngược thứ tự). Khối phá lên chạy trước rồi khối phá xuống chạy sau, xu hướng kết thúc là giảm, cả hai đường BOS/CHoCH đều được vẽ, và các alert/điểm ◉ có thể cùng phát. Trường hợp hiếm nhưng có thể gặp trên dữ liệu biến động mạnh.
- Chữ trên chart và alert dùng tiêu chí khác nhau. Chữ "CHoCH" phụ thuộc ô "Show CHoCH" và chỉ ghi khi xu hướng cũ là ngược chiều; điểm ◉ / alert Trend Change còn bật cả ở cú phá vỡ đầu tiên (khi chữ ghi "BOS"). Hai thứ này sẽ không khớp nhau 100%.
- Trần 500 nhãn dùng chung. Nhãn swing HH/LH/HL/LL và chữ BOS/CHoCH cùng tính vào giới hạn 500. Trên lịch sử dài, các nhãn cũ nhất sẽ biến mất khi chart có quá nhiều swing; tắt "Show Swing Labels" để giữ lại chữ BOS/CHoCH lâu hơn.
- Cho Phase B (nếu cần đọc trạng thái): các biến prevHigh, prevLow, prevBreakDir, highBroken, lowBroken, bullishChange, bearishChange, bullishArrow, bearishArrow, upper, lower đều nằm ở cấp toàn cục nên có thể đọc trực tiếp. Chỉ báo không lưu lịch sử các mức cũ, chỉ có đúng một đỉnh và một đáy gần nhất.


