//+------------------------------------------------------------------+ //| rsi2.mq5 | //| BẢN BÁO CÁO 2 KHUNG KHI 1 BÊN CHẠM - CHO SẾP ĐÀM | //+------------------------------------------------------------------+ #property strict input string InpTeleToken = "8738711780:AAHLhl3vBM-hlOU1EdkjjxbuBNu-z9eWgio"; input string InpTeleChatID = "6550120410"; // --- TẠO CÁC Ô ĐIỀN THÔNG SỐ TRÊN BẢNG INPUTS --- input double InpUpper_M1 = 90.0; // Ngưỡng Quá Mua M1 (Upper) input double InpLower_M1 = 20.0; // Ngưỡng Quá Bán M1 (Lower) input double InpUpper_M5 = 80.0; // Ngưỡng Quá Mua M5 (Upper) input double InpLower_M5 = 15.0; // Ngưỡng Quá Bán M5 (Lower) // --- CÀI ĐẶT KHUNG GIỜ YÊN LẶNG (TẮT THÔNG BÁO) --- input int InpQuietStartHour = 0; // Giờ bắt đầu tắt thông báo (0 = 12h đêm) input int InpQuietEndHour = 5; // Giờ bật lại thông báo (5 = 5h sáng) int h1, h2; datetime lastAlert = 0; int OnInit() { h1 = iRSI(_Symbol, PERIOD_M1, 14, PRICE_CLOSE); h2 = iRSI(_Symbol, PERIOD_M5, 14, PRICE_CLOSE); if(h1 == INVALID_HANDLE || h2 == INVALID_HANDLE) { Print("❌ Lỗi khởi tạo Indicator Handles!"); return(INIT_FAILED); } SendTele("KHOI_DONG_RSI_OK"); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { IndicatorRelease(h1); IndicatorRelease(h2); } // --- HÀM KIỂM TRA KHUNG GIỜ TẮT THÔNG BÁO --- bool IsQuietTime(datetime current_time) { MqlDateTime dt; TimeToStruct(current_time, dt); if(InpQuietStartHour < InpQuietEndHour) { if(dt.hour >= InpQuietStartHour && dt.hour < InpQuietEndHour) return true; } else if(InpQuietStartHour > InpQuietEndHour) { if(dt.hour >= InpQuietStartHour || dt.hour < InpQuietEndHour) return true; } return false; } void OnTick() { // Chặn việc bắn tin quá nhiều trong cùng 1 nến M1 datetime currentTime = iTime(_Symbol, PERIOD_M1, 0); if(currentTime == lastAlert) return; // Kiểm tra giờ Việt Nam trên máy (TimeLocal) để nghỉ từ 00h - 05h sáng if(IsQuietTime(TimeLocal())) return; double r1[1], r2[1]; // Lấy giá trị của nến vừa đóng (index 1) if(CopyBuffer(h1, 0, 1, 1, r1) <= 0 || CopyBuffer(h2, 0, 1, 1, r2) <= 0) return; bool isSellM1 = (r1[0] >= InpUpper_M1); bool isBuyM1 = (r1[0] <= InpLower_M1); bool isSellM5 = (r2[0] >= InpUpper_M5); bool isBuyM5 = (r2[0] <= InpLower_M5); // Chỉ xử lý nếu có ít nhất 1 khung chạm ngưỡng if(isSellM1 || isBuyM1 || isSellM5 || isBuyM5) { string side = ""; if(isSellM1 || isSellM5) side = "SELL"; else if(isBuyM1 || isBuyM5) side = "BUY"; // Định dạng 1 dòng duy nhất: ACTION SYMBOL RSI1 RSI2 string msg = side + " " + _Symbol + " " + DoubleToString(r1[0], 1) + " " + DoubleToString(r2[0], 1); // 1. Thông báo trên MT5 PlaySound("alert.wav"); Alert(msg); // 2. Gửi báo cáo về Telegram SendTele(msg); lastAlert = currentTime; } } // Hàm mã hóa chuỗi để chuẩn hóa URL string UrlEncode(string text) { string result = ""; uchar array[]; StringToCharArray(text, array, 0, WHOLE_ARRAY, CP_UTF8); for(int i = 0; i < ArraySize(array) - 1; i++) { if((array[i] >= 'a' && array[i] <= 'z') || (array[i] >= 'A' && array[i] <= 'Z') || (array[i] >= '0' && array[i] <= '9') || array[i] == '.' || array[i] == '-' || array[i] == '_' || array[i] == '~') { result += ShortToString(array[i]); } else { result += StringFormat("%%%02X", array[i]); } } return result; } void SendTele(string txt) { string url = "https://api.telegram.org/bot" + InpTeleToken + "/sendMessage"; string headers = "Content-Type: application/x-www-form-urlencoded\r\n"; string params = "chat_id=" + InpTeleChatID + "&text=" + UrlEncode(txt); char data[], res[]; string res_headers; StringToCharArray(params, data, 0, WHOLE_ARRAY, CP_UTF8); if(ArraySize(data) > 0) ArrayResize(data, ArraySize(data) - 1); int check = WebRequest("POST", url, headers, 5000, data, res, res_headers); if(check == 200) { Print("✅ Telegram OK!"); } else { Print("❌ Lỗi gửi Telegram. Code: ", check); } }