diff --git a/Experts/BellMainPriceAction.ex5 b/Experts/BellMainPriceAction.ex5 new file mode 100644 index 0000000..2ad91fb Binary files /dev/null and b/Experts/BellMainPriceAction.ex5 differ diff --git a/Experts/BellMainPriceAction.mq5 b/Experts/BellMainPriceAction.mq5 new file mode 100644 index 0000000..01b9b10 --- /dev/null +++ b/Experts/BellMainPriceAction.mq5 @@ -0,0 +1,165 @@ +//+------------------------------------------------------------------+ +//| EA_Trend_EMA50_EMA200.mq5 | +//| Phiên bản: 1.0 | +//| Mục đích: | +//| - Xác định xu hướng bằng EMA50 & EMA200 (m15) | +//| - Vào lệnh trên M5 khi có tín hiệu: 2 đáy / 2 đỉnh / nến nhấn chìm | +//| - Rủi ro cố định: 1% Equity mỗi lệnh | +//| - Giới hạn tối đa 2 lệnh mở cùng lúc | +//| - Tùy chọn hiển thị EMA lên biểu đồ | +//+------------------------------------------------------------------+ +#property copyright "Bell Hyperpush" +#property version "1.00" +#property strict + +#include +CTrade trade; +int handleEMA50 = INVALID_HANDLE; +int handleEMA200 = INVALID_HANDLE; + +// ================== INPUTS ========================================= +input ENUM_TIMEFRAMES TrendTF = PERIOD_M15; // khung thời gian dùng để lọc xu hướng +input ENUM_TIMEFRAMES EntryTF = PERIOD_M5; // khung thời gian để tìm điểm vào +input int EMA_Fast = 50; // EMA nhanh +input int EMA_Slow = 200; // EMA chậm +input double RiskPercent = 1.0; // rủi ro % equity cho mỗi lệnh +input double TP_Multiplier = 2.0; // tỉ lệ TP = Risk * multiplier +input int MaxOpenPositions = 2; // tối đa 2 lệnh mở +input double DoubleTolerancePoints = 30; // dung sai giữa 2 đáy/đỉnh +input int MinBarsBetweenDouble = 4; // khoảng cách tối thiểu giữa 2 đáy/đỉnh +input int SL_Pips_Default = 35; // SL mặc định (points) +input int Slippage = 10; // trượt giá tối đa +input bool VisualizeEMAs = true; // có vẽ EMA lên chart không +input int TrendShift = 1; // shift dùng để đọc nến đóng (tránh nến đang hình thành) +input int StructureRecentOffset = 1; // offset cho nến recent khi kiểm tra cấu trúc (high1/low1) +input int StructurePrevOffset = 2; // offset cho nến trước đó khi kiểm tra cấu trúc (high2/low2) + +// ================== FUNCTIONS ===================================== + +// ----- Enums for structured states (avoid hard-coded strings) ----- +enum TREND_STRUCTURE { STRUCTURE_NEUTRAL = 0, STRUCTURE_HH_HL, STRUCTURE_LH_LL, STRUCTURE_SIDEWAY }; +enum EMA_COND { EMA_INSUFFICIENT = 0, EMA_UPTREND, EMA_DOWNTREND, EMA_NEUTRAL }; +enum TREND_RESULT { TREND_NEUTRAL = 0, TREND_UPTREND, TREND_DOWNTREND, TREND_SIDEWAY_RESULT }; + +string StructureToString(const int s) { + switch(s) { + case STRUCTURE_HH_HL: return "HH-HL (Uptrend)"; + case STRUCTURE_LH_LL: return "LH-LL (Downtrend)"; + case STRUCTURE_SIDEWAY: return "Sideway"; + default: return "Neutral"; + } +} + +string EmaConditionToString(const int e) { + switch(e) { + case EMA_UPTREND: return "EMA Uptrend"; + case EMA_DOWNTREND: return "EMA Downtrend"; + case EMA_NEUTRAL: return "EMA Neutral"; + default: return "EMA InsufficientData"; + } +} + +string TrendResultToString(const int r) { + switch(r) { + case TREND_UPTREND: return "UPTREND"; + case TREND_DOWNTREND: return "DOWNTREND"; + case TREND_SIDEWAY_RESULT: return "SIDEWAY"; + default: return "NEUTRAL"; + } +} + +// Xác định xu hướng hiện tại +string GetTrendDirection() { + int shift = TrendShift; // tránh dùng nến đang chạy (mặc định = 1) + double emaFast = 0.0; + double emaSlow = 0.0; + double buf[]; + + // read EMA50 value by copying buffer from handle + if(handleEMA50 != INVALID_HANDLE) { + if(CopyBuffer(handleEMA50, 0, shift, 1, buf) > 0) emaFast = buf[0]; + } + + // read EMA200 value by copying buffer from handle + if(handleEMA200 != INVALID_HANDLE) { + if(CopyBuffer(handleEMA200, 0, shift, 1, buf) > 0) emaSlow = buf[0]; + } + double priceClose = iClose(_Symbol, TrendTF, shift); + + // Lấy giá cao thấp theo cấu hình offsets (recent vs prev) + double high1 = iHigh(_Symbol, TrendTF, StructureRecentOffset); + double high2 = iHigh(_Symbol, TrendTF, StructurePrevOffset); + double low1 = iLow(_Symbol, TrendTF, StructureRecentOffset); + double low2 = iLow(_Symbol, TrendTF, StructurePrevOffset); + + int structureEnum = STRUCTURE_NEUTRAL; + int emaEnum = EMA_INSUFFICIENT; + int trendEnum = TREND_NEUTRAL; + + // --- B1: Kiểm tra cấu trúc xu hướng + if(high1 > high2 && low1 > low2) + structureEnum = STRUCTURE_HH_HL; + else if(high1 < high2 && low1 < low2) + structureEnum = STRUCTURE_LH_LL; + else + structureEnum = STRUCTURE_SIDEWAY; + + // --- B2: Kiểm tra EMA (an toàn: đảm bảo dữ liệu hợp lệ) + if(priceClose <= 0.0 || emaFast <= 0.0 || emaSlow <= 0.0) + emaEnum = EMA_INSUFFICIENT; + else if(emaFast > emaSlow && priceClose > emaFast) + emaEnum = EMA_UPTREND; + else if(emaFast < emaSlow && priceClose < emaFast) + emaEnum = EMA_DOWNTREND; + else + emaEnum = EMA_NEUTRAL; + + // --- B3: Tổng hợp kết luận + if(structureEnum == STRUCTURE_HH_HL && emaEnum == EMA_UPTREND) + trendEnum = TREND_UPTREND; + else if(structureEnum == STRUCTURE_LH_LL && emaEnum == EMA_DOWNTREND) + trendEnum = TREND_DOWNTREND; + else + trendEnum = TREND_SIDEWAY_RESULT; + + // --- B4: Log chi tiết (debug) + PrintFormat("[TREND DEBUG] === %s ===", TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS)); + PrintFormat("EMA50=%.2f | EMA200=%.2f | Close=%.2f", emaFast, emaSlow, priceClose); + PrintFormat("Structure: %s | EMA: %s | => TREND: %s", + StructureToString(structureEnum), EmaConditionToString(emaEnum), TrendResultToString(trendEnum)); + + return TrendResultToString(trendEnum); +} + + +// ================== VÒNG LẶP CHÍNH ================================ +void OnTick() +{ + static datetime lastCheck = 0; + + // chỉ check 1 lần mỗi phút + if(TimeCurrent() - lastCheck >= 60) + { + string trend = GetTrendDirection(); + Comment("Current Trend (", EnumToString(TrendTF), "): ", trend); + lastCheck = TimeCurrent(); + } +} + + +// ================== KHỞI TẠO & KẾT THÚC =========================== +int OnInit() { + // create EMA indicator handles + handleEMA50 = iMA(_Symbol, TrendTF, EMA_Fast, 0, MODE_EMA, PRICE_CLOSE); + handleEMA200 = iMA(_Symbol, TrendTF, EMA_Slow, 0, MODE_EMA, PRICE_CLOSE); + if(handleEMA50 == INVALID_HANDLE || handleEMA200 == INVALID_HANDLE) { + Print("Failed to create EMA handles. Err=", GetLastError()); + return(INIT_FAILED); + } + return(INIT_SUCCEEDED); +} + +void OnDeinit(const int reason) { + if(handleEMA50 != INVALID_HANDLE) IndicatorRelease(handleEMA50); + if(handleEMA200 != INVALID_HANDLE) IndicatorRelease(handleEMA200); +} diff --git a/Experts/BellPriceActionWithEma50EA.ex5 b/Experts/BellPriceActionWithEma50EA.ex5 new file mode 100644 index 0000000..bcbda84 Binary files /dev/null and b/Experts/BellPriceActionWithEma50EA.ex5 differ diff --git a/Experts/testMovingAverageEA.ex5 b/Experts/testMovingAverageEA.ex5 new file mode 100644 index 0000000..50c98f5 Binary files /dev/null and b/Experts/testMovingAverageEA.ex5 differ diff --git a/Logs/20251008.log b/Logs/20251008.log deleted file mode 100644 index 7bd476f..0000000 Binary files a/Logs/20251008.log and /dev/null differ diff --git a/Profiles/deleted/01.chr b/Profiles/deleted/01.chr deleted file mode 100644 index d5a1ba7..0000000 Binary files a/Profiles/deleted/01.chr and /dev/null differ diff --git a/Profiles/deleted/02.chr b/Profiles/deleted/02.chr deleted file mode 100644 index 0641b3f..0000000 Binary files a/Profiles/deleted/02.chr and /dev/null differ diff --git a/Profiles/deleted/03.chr b/Profiles/deleted/03.chr deleted file mode 100644 index 0654c8a..0000000 Binary files a/Profiles/deleted/03.chr and /dev/null differ diff --git a/Profiles/deleted/04.chr b/Profiles/deleted/04.chr deleted file mode 100644 index 1fa1fdf..0000000 Binary files a/Profiles/deleted/04.chr and /dev/null differ diff --git a/experts.dat b/experts.dat index 51ae460..2d78090 100644 Binary files a/experts.dat and b/experts.dat differ