From baf29f262e69bb2a0e4523acb4ba4179b82a8506 Mon Sep 17 00:00:00 2001 From: Bell Date: Sun, 10 May 2026 21:38:56 +0700 Subject: [PATCH] Logic indicator --- .../RsiMomentumIndicator.ex5 | Bin 0 -> 19292 bytes .../RsiMomentumIndicator.mq5 | 190 +++++++++++++----- 2 files changed, 136 insertions(+), 54 deletions(-) create mode 100644 Indicators/RsiMomentumIndicator/RsiMomentumIndicator.ex5 rename Indicators/{ => RsiMomentumIndicator}/RsiMomentumIndicator.mq5 (54%) diff --git a/Indicators/RsiMomentumIndicator/RsiMomentumIndicator.ex5 b/Indicators/RsiMomentumIndicator/RsiMomentumIndicator.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..1bf30f1f9013d4d3fce2258c7ec730ab3d27ff51 GIT binary patch literal 19292 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 literal 0 HcmV?d00001 diff --git a/Indicators/RsiMomentumIndicator.mq5 b/Indicators/RsiMomentumIndicator/RsiMomentumIndicator.mq5 similarity index 54% rename from Indicators/RsiMomentumIndicator.mq5 rename to Indicators/RsiMomentumIndicator/RsiMomentumIndicator.mq5 index 439b3b9..503905f 100644 --- a/Indicators/RsiMomentumIndicator.mq5 +++ b/Indicators/RsiMomentumIndicator/RsiMomentumIndicator.mq5 @@ -7,15 +7,15 @@ #property copyright "RsiMomentumIndicator" #property version "1.00" #property indicator_separate_window -#property indicator_buffers 3 +#property indicator_buffers 4 #property indicator_plots 3 #property indicator_minimum 0 #property indicator_maximum 100 -// --- Buffer 0: RSI14 --- +// --- Plot 0 (Buffer 0 + Color buffer 3): RSI14 với màu thay đổi theo vùng extreme --- #property indicator_label1 "RSI(14)" -#property indicator_type1 DRAW_LINE -#property indicator_color1 clrMediumOrchid +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrMediumOrchid, clrRed // index 0 = bình thường, index 1 = extreme #property indicator_style1 STYLE_SOLID #property indicator_width1 2 @@ -42,6 +42,15 @@ input int InpEMA9Period = 9; input int InpWMA45Period = 45; input int InpEMA200Period = 200; +input group "Bộ lọc trend" +input int InpTrendConfirmBars = 2; // số nến liên tiếp phải đóng cùng phía EMA200 + +input group "Bộ lọc RSI extreme" +input double InpRSIOverbought = 70.0; // RSI ≥ ngưỡng này → bỏ qua tín hiệu BUY +input double InpRSIOversold = 30.0; // RSI ≤ ngưỡng này → bỏ qua tín hiệu SELL +input double InpRSIExtremeHigh = 75.0; // RSI > ngưỡng này → tô đỏ trên biểu đồ +input double InpRSIExtremeLow = 25.0; // RSI < ngưỡng này → tô đỏ trên biểu đồ + input group "Mũi tên giao cắt" input color InpArrowUpColor = clrLime; // màu mũi tên khi RSI cắt lên WMA45 input color InpArrowDownColor = clrTomato; // màu mũi tên khi RSI cắt xuống WMA45 @@ -57,6 +66,7 @@ input bool InpShowPanel = true; double buf_RSI[]; double buf_EMA9[]; double buf_WMA45[]; +double buf_RSI_color[]; // color index buffer cho RSI (0 = normal, 1 = extreme red) int h_RSI = INVALID_HANDLE; int h_EMA9 = INVALID_HANDLE; @@ -103,17 +113,31 @@ void UpdateLabel(const string name, const string text, const color clr) int OnInit() { // Đăng ký buffer — đặt AS_SERIES để [0] = nến hiện tại - SetIndexBuffer(0, buf_RSI, INDICATOR_DATA); - SetIndexBuffer(1, buf_EMA9, INDICATOR_DATA); - SetIndexBuffer(2, buf_WMA45, INDICATOR_DATA); + SetIndexBuffer(0, buf_RSI, INDICATOR_DATA); + SetIndexBuffer(1, buf_EMA9, INDICATOR_DATA); + SetIndexBuffer(2, buf_WMA45, INDICATOR_DATA); + SetIndexBuffer(3, buf_RSI_color, INDICATOR_COLOR_INDEX); - ArraySetAsSeries(buf_RSI, true); - ArraySetAsSeries(buf_EMA9, true); - ArraySetAsSeries(buf_WMA45, true); + ArraySetAsSeries(buf_RSI, true); + ArraySetAsSeries(buf_EMA9, true); + ArraySetAsSeries(buf_WMA45, true); + ArraySetAsSeries(buf_RSI_color, true); IndicatorSetString (INDICATOR_SHORTNAME, StringFormat("RsiMom(%d)", InpRSIPeriod)); IndicatorSetInteger(INDICATOR_DIGITS, 2); + // Vẽ 2 đường ngang: Overbought (70) và Oversold (30) + IndicatorSetInteger(INDICATOR_LEVELS, 2); + IndicatorSetDouble (INDICATOR_LEVELVALUE, 0, InpRSIOverbought); + IndicatorSetDouble (INDICATOR_LEVELVALUE, 1, InpRSIOversold); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 0, clrSilver); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 1, clrSilver); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 0, STYLE_DOT); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 1, STYLE_DOT); + IndicatorSetInteger(INDICATOR_LEVELWIDTH, 0, 1); + IndicatorSetInteger(INDICATOR_LEVELWIDTH, 1, 1); + PlotIndexSetString (0, PLOT_LABEL, "RSI(14)"); + // Tạo handles chỉ báo h_RSI = iRSI(_Symbol, _Period, InpRSIPeriod, PRICE_CLOSE); if (h_RSI == INVALID_HANDLE) @@ -186,98 +210,156 @@ int OnCalculate(const int rates_total, if (CopyBuffer(h_EMA9, 0, 0, rates_total, buf_EMA9) < rates_total) return prev_calculated; if (CopyBuffer(h_WMA45, 0, 0, rates_total, buf_WMA45) < rates_total) return prev_calculated; + // Tô màu RSI theo vùng extreme: + // value > InpRSIExtremeHigh hoặc < InpRSIExtremeLow → color index 1 (đỏ) + // ngược lại → color index 0 (mặc định) + // Buffer đang AS_SERIES → [0] = bar mới nhất; quét toàn bộ cho đơn giản (O(N) nhẹ). + for (int i = 0; i < rates_total; i++) + { + const double v = buf_RSI[i]; + buf_RSI_color[i] = (v > InpRSIExtremeHigh || v < InpRSIExtremeLow) ? 1.0 : 0.0; + } + // Số nến cần quét để phát hiện giao cắt mới int barsToScan = (prev_calculated == 0) ? rates_total - 2 : (rates_total - prev_calculated + 2); barsToScan = MathMin(barsToScan, rates_total - 2); - // Sao chép time, high, low vào mảng cục bộ AS_SERIES để dùng trong vòng lặp + // Sao chép time, high, low, close và EMA200 để phát hiện giao cắt + lọc trend + // +InpTrendConfirmBars vì cần check N nến liên tiếp đóng cùng phía EMA200 + const int trendN = MathMax(1, InpTrendConfirmBars); + const int need = barsToScan + 2 + trendN; datetime timeArr[]; - double highArr[]; - double lowArr[]; - ArraySetAsSeries(timeArr, true); - ArraySetAsSeries(highArr, true); - ArraySetAsSeries(lowArr, true); + double highArr[], lowArr[], closeArr[], ema200Arr[]; + ArraySetAsSeries(timeArr, true); + ArraySetAsSeries(highArr, true); + ArraySetAsSeries(lowArr, true); + ArraySetAsSeries(closeArr, true); + ArraySetAsSeries(ema200Arr, true); - if (CopyTime (_Symbol, _Period, 0, barsToScan + 2, timeArr) < barsToScan + 2) return prev_calculated; - if (CopyHigh (_Symbol, _Period, 0, barsToScan + 2, highArr) < barsToScan + 2) return prev_calculated; - if (CopyLow (_Symbol, _Period, 0, barsToScan + 2, lowArr) < barsToScan + 2) return prev_calculated; + if (CopyTime (_Symbol, _Period, 0, need, timeArr) < need) return prev_calculated; + if (CopyHigh (_Symbol, _Period, 0, need, highArr) < need) return prev_calculated; + if (CopyLow (_Symbol, _Period, 0, need, lowArr) < need) return prev_calculated; + if (CopyClose (_Symbol, _Period, 0, need, closeArr) < need) return prev_calculated; + if (CopyBuffer(h_EMA200, 0, 0, need, ema200Arr) < need) return prev_calculated; const double arrowOffset = InpArrowOffsetPts * _Point; - // Phát hiện giao cắt RSI vs WMA45 và vẽ mũi tên lên chart chính + // Phát hiện giao cắt RSI vs WMA45, chỉ vẽ khi khớp với trend EMA200 for (int i = barsToScan; i >= 1; i--) { - // Tránh truy cập vượt quá phạm vi buffer - if (i + 1 >= rates_total) continue; + if (i + 1 >= rates_total) continue; + if (i + trendN >= rates_total) continue; // không đủ lịch sử cho N nến trend + if (ema200Arr[i] <= 0.0) continue; // EMA200 chưa tính đủ bars const bool crossUp = (buf_RSI[i+1] <= buf_WMA45[i+1]) && (buf_RSI[i] > buf_WMA45[i]); const bool crossDown = (buf_RSI[i+1] >= buf_WMA45[i+1]) && (buf_RSI[i] < buf_WMA45[i]); if (!crossUp && !crossDown) continue; + // Lọc theo trend EMA200: cần N nến LIÊN TIẾP gần nhất đều đóng cùng phía + // Quét từ nến tín hiệu i → i+N-1 + bool trendUp = true; + bool trendDown = true; + for (int k = 0; k < trendN; k++) + { + const int idx = i + k; + if (ema200Arr[idx] <= 0.0) { trendUp = false; trendDown = false; break; } + if (closeArr[idx] <= ema200Arr[idx]) trendUp = false; + if (closeArr[idx] >= ema200Arr[idx]) trendDown = false; + if (!trendUp && !trendDown) break; + } + + // Vị trí EMA9 vs WMA45 — kiểm tra "lực mua/bán mới bắt đầu chiếm ưu thế" + // BUY: EMA9 vẫn dưới WMA45 (lực mua chỉ vừa nhú lên qua RSI cross) + // SELL: EMA9 vẫn trên WMA45 (lực bán chỉ vừa nhú xuống) + const bool ema9BelowWma = (buf_EMA9[i] < buf_WMA45[i]); + const bool ema9AboveWma = (buf_EMA9[i] > buf_WMA45[i]); + + // Slope EMA9 — phải đang hướng cùng chiều với tín hiệu + const bool ema9SlopeUp = (buf_EMA9[i] > buf_EMA9[i+1]); + const bool ema9SlopeDown = (buf_EMA9[i] < buf_EMA9[i+1]); + + // Lọc RSI extreme — không mua đỉnh, không bán đáy + // RSI ≥ overbought → bỏ tín hiệu BUY + // RSI ≤ oversold → bỏ tín hiệu SELL + const bool rsiOkBuy = (buf_RSI[i] < InpRSIOverbought); + const bool rsiOkSell = (buf_RSI[i] > InpRSIOversold); + + // Tín hiệu hợp lệ khi đủ 5 điều kiện + const bool validBuy = crossUp && trendUp && ema9BelowWma && ema9SlopeUp && rsiOkBuy; + const bool validSell = crossDown && trendDown && ema9AboveWma && ema9SlopeDown && rsiOkSell; + + if (!validBuy && !validSell) continue; + // Dùng timestamp làm tên duy nhất để tránh tạo trùng object const string arrowName = OBJ_PREFIX + "CR_" + IntegerToString((int)timeArr[i]); - if (ObjectFind(0, arrowName) >= 0) continue; // đã có → bỏ qua + if (ObjectFind(0, arrowName) >= 0) continue; - if (crossUp) + if (validBuy) { - // Mũi tên lên dưới đáy nến + // Mũi tên lên (↑) đặt dưới đáy nến — tín hiệu BUY trong uptrend + // ANCHOR_TOP: điểm anchor là đỉnh icon → arrow nằm xuôi xuống dưới price + // → tip ↑ ở phía trên, sát đáy nến (cách lowArr[i] một khoảng arrowOffset) const double price = lowArr[i] - arrowOffset; ObjectCreate(0, arrowName, OBJ_ARROW, 0, timeArr[i], price); - ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, 233); // ↑ Wingdings + ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, 233); + ObjectSetInteger(0, arrowName, OBJPROP_ANCHOR, ANCHOR_TOP); ObjectSetInteger(0, arrowName, OBJPROP_COLOR, InpArrowUpColor); ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, InpArrowSize); ObjectSetInteger(0, arrowName, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, arrowName, OBJPROP_HIDDEN, true); ObjectSetString (0, arrowName, OBJPROP_TOOLTIP, - StringFormat("RSI cắt lên WMA45 | %s | RSI=%.2f WMA45=%.2f", + StringFormat("BUY signal\n%s\nRSI=%.2f EMA9=%.2f (slope+) WMA45=%.2f\nEMA200=%.5f (Uptrend)", TimeToString(timeArr[i], TIME_DATE|TIME_MINUTES), - buf_RSI[i], buf_WMA45[i])); + buf_RSI[i], buf_EMA9[i], buf_WMA45[i], ema200Arr[i])); } - else // crossDown + else // validSell { - // Mũi tên xuống trên đỉnh nến + // Mũi tên xuống (↓) đặt trên đỉnh nến — tín hiệu SELL trong downtrend + // ANCHOR_BOTTOM: điểm anchor là đáy icon → arrow nằm ngược lên trên price + // → tip ↓ ở phía dưới, sát đỉnh nến (cách highArr[i] một khoảng arrowOffset) const double price = highArr[i] + arrowOffset; ObjectCreate(0, arrowName, OBJ_ARROW, 0, timeArr[i], price); - ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, 234); // ↓ Wingdings + ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, 234); + ObjectSetInteger(0, arrowName, OBJPROP_ANCHOR, ANCHOR_BOTTOM); ObjectSetInteger(0, arrowName, OBJPROP_COLOR, InpArrowDownColor); ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, InpArrowSize); ObjectSetInteger(0, arrowName, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, arrowName, OBJPROP_HIDDEN, true); ObjectSetString (0, arrowName, OBJPROP_TOOLTIP, - StringFormat("RSI cắt xuống WMA45 | %s | RSI=%.2f WMA45=%.2f", + StringFormat("SELL signal\n%s\nRSI=%.2f EMA9=%.2f (slope-) WMA45=%.2f\nEMA200=%.5f (Downtrend)", TimeToString(timeArr[i], TIME_DATE|TIME_MINUTES), - buf_RSI[i], buf_WMA45[i])); + buf_RSI[i], buf_EMA9[i], buf_WMA45[i], ema200Arr[i])); } } // Cập nhật panel thông tin (dùng nến vừa đóng = index 1) - if (InpShowPanel && rates_total > 2) + // closeArr và ema200Arr đã được copy ở trên — dùng lại luôn + if (InpShowPanel && rates_total > trendN + 1 && ema200Arr[1] > 0.0) { - double ema200Arr[]; - ArraySetAsSeries(ema200Arr, true); - - double closeArr[]; - ArraySetAsSeries(closeArr, true); - - bool panelOk = (CopyBuffer(h_EMA200, 0, 0, 3, ema200Arr) >= 3) && - (CopyClose(_Symbol, _Period, 0, 3, closeArr) >= 3); - - if (panelOk && ema200Arr[1] > 0.0) + // Áp dụng cùng quy tắc N nến liên tiếp cho panel hiển thị + bool panelTrendUp = true; + bool panelTrendDown = true; + for (int k = 0; k < trendN; k++) { - const bool trendUp = (closeArr[1] > ema200Arr[1]); - const color trendClr = trendUp ? InpArrowUpColor : InpArrowDownColor; - const string trendTxt = trendUp - ? "Trend : UPTREND (Close > EMA200)" - : "Trend : DOWNTREND (Close < EMA200)"; - - UpdateLabel(LBL_TREND, trendTxt, trendClr); - UpdateLabel(LBL_RSI_VAL, StringFormat("RSI : %6.2f", buf_RSI[1]), clrMediumOrchid); - UpdateLabel(LBL_EMA9VAL, StringFormat("EMA9 : %6.2f", buf_EMA9[1]), clrDarkOrange); - UpdateLabel(LBL_WMA45VAL, StringFormat("WMA45 : %6.2f", buf_WMA45[1]), clrDodgerBlue); + const int idx = 1 + k; + if (ema200Arr[idx] <= 0.0) { panelTrendUp = false; panelTrendDown = false; break; } + if (closeArr[idx] <= ema200Arr[idx]) panelTrendUp = false; + if (closeArr[idx] >= ema200Arr[idx]) panelTrendDown = false; } + + string trendTxt; + color trendClr; + if (panelTrendUp) { trendTxt = StringFormat("Trend : UPTREND (%d closes > EMA200)", trendN); trendClr = InpArrowUpColor; } + else if (panelTrendDown) { trendTxt = StringFormat("Trend : DOWNTREND (%d closes < EMA200)", trendN); trendClr = InpArrowDownColor; } + else { trendTxt = "Trend : RANGE / SWITCHING"; trendClr = clrSilver; } + + UpdateLabel(LBL_TREND, trendTxt, trendClr); + UpdateLabel(LBL_RSI_VAL, StringFormat("RSI : %6.2f", buf_RSI[1]), clrMediumOrchid); + UpdateLabel(LBL_EMA9VAL, StringFormat("EMA9 : %6.2f", buf_EMA9[1]), clrDarkOrange); + UpdateLabel(LBL_WMA45VAL, StringFormat("WMA45 : %6.2f", buf_WMA45[1]),clrDodgerBlue); } ChartRedraw(0);