diff --git a/Experts/BellPriceActionWithEma50EA.ex5 b/Experts/BellPriceActionWithEma50EA.ex5 index bcbda84..a9ce463 100644 Binary files a/Experts/BellPriceActionWithEma50EA.ex5 and b/Experts/BellPriceActionWithEma50EA.ex5 differ diff --git a/Experts/BellPriceActionWithEma50EA.txt b/Experts/BellPriceActionWithEma50EA.txt deleted file mode 100644 index ab9ed29..0000000 --- a/Experts/BellPriceActionWithEma50EA.txt +++ /dev/null @@ -1,358 +0,0 @@ -//+------------------------------------------------------------------+ -//| EA_Trend_EMA50_EMA200_M5_M1.mq5 | -//| Phiên bản: 1.0 | -//| Mục đích: | -//| - Xác định xu hướng bằng EMA50 & EMA200 (M5) | -//| - Vào lệnh trên M1 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; - -// ================== 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 (điểm) -input int Slippage = 10; // trượt giá tối đa -input bool VisualizeEMAs = true; // có vẽ EMA lên chart không - -// ================== BIẾN TOÀN CỤC ================================= -int handleEMA50 = INVALID_HANDLE; -int handleEMA200 = INVALID_HANDLE; - -// ================== HÀM HỖ TRỢ ==================================== - -// ---- Đếm số lệnh đang mở cho symbol hiện tại ---- -int CountOpenPositionsSymbol() { - int count = 0; - - for(int i=0; i open1) { - // Và thân nến sau bao phủ hoàn toàn thân nến trước - if(close1 > open2 && open1 < close2) - return true; - } - - return false; -} - -// ---- Kiểm tra mô hình nến nhấn chìm giảm ---- -bool IsBearishEngulfing(ENUM_TIMEFRAMES tf) { - double open1 = iOpen(_Symbol, tf, 1); - double close1 = iClose(_Symbol, tf, 1); - double open2 = iOpen(_Symbol, tf, 2); - double close2 = iClose(_Symbol, tf, 2); - - // Nến trước tăng (xanh), nến sau giảm (đỏ) - if(close2 > open2 && close1 < open1) { - // Và thân nến sau bao phủ hoàn toàn thân nến trước - if(close1 < open2 && open1 > close2) - return true; - } - return false; -} - -// ---- Phát hiện mô hình 2 ĐÁY ---- -bool DetectDoubleBottom(ENUM_TIMEFRAMES tf, int lookbackBars, double tolerancePoints, double &levelPrice) { - levelPrice = 0.0; - - // Duyệt từng nến (bắt đầu từ nến thứ 2 để tránh lỗi biên) - for(int i=2; i qua nến tiếp - - // Khi đã có đáy thứ nhất, tìm đáy thứ hai cách ít nhất MinBarsBetweenDouble nến - for(int j=i+MinBarsBetweenDouble; j thoát hàm - } - } - } - - return false; // không tìm thấy -} - -// ---- Phát hiện mô hình 2 ĐỈNH ---- -bool DetectDoubleTop(ENUM_TIMEFRAMES tf, int lookbackBars, double tolerancePoints, double &levelPrice) { - levelPrice = 0.0; - - // Duyệt nến để tìm đỉnh đầu tiên - for(int i=2; i iHigh(_Symbol, tf, i-1) && h1 > iHigh(_Symbol, tf, i+1)); - if(!isHigh1) continue; - - // Tìm đỉnh thứ 2 sau đỉnh đầu - for(int j=i+MinBarsBetweenDouble; j iHigh(_Symbol, tf, j-1) && h2 > iHigh(_Symbol, tf, j+1)); - if(!isHigh2) continue; - - // So sánh độ cao giữa 2 đỉnh - double diffPoints = MathAbs(h1 - h2)/_Point; - - // Nếu 2 đỉnh gần bằng nhau → xác nhận mô hình - if(diffPoints <= tolerancePoints) { - levelPrice = MathMax(h1, h2); // lấy đỉnh cao hơn làm mốc - return true; - } - } - } - - return false; -} - -// ---- Tính khối lượng lệnh dựa theo % rủi ro ---- -double CalculateLotByRisk(double riskPercent, double stopLossPoints) { - if(stopLossPoints <= 0) - return(SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)); - - double equity = AccountInfoDouble(ACCOUNT_EQUITY); - double riskMoney = equity * (riskPercent / 100.0); - double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); - double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE); - - // Nếu broker không trả tickValue chuẩn → fallback - if(tickValue <= 0 || tickSize <= 0) { - double fallback = riskMoney / (stopLossPoints * _Point); - double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP); - double lot = MathMax(SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN), - MathFloor(fallback/step)*step); - return lot; - } - - // Giá trị mỗi point cho 1 lot - double valuePerPointFor1Lot = tickValue / tickSize; - - // Tính số lot phù hợp với rủi ro cho phép - double lots = riskMoney / (stopLossPoints * valuePerPointFor1Lot); - - // Làm tròn theo bước lot tối thiểu - double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP); - if(step <= 0) step = 0.01; - lots = MathFloor(lots/step)*step; - - double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN); - if(lots < minLot) lots = minLot; - - return NormalizeDouble(lots,2); -} - -// ---- Bộ lọc xu hướng EMA ---- -// Trả về: -// 1 -> chỉ cho BUY -// -1 -> chỉ cho SELL -// 0 -> không rõ xu hướng -int EMAFilter() { - double buf50[], buf200[]; - - if(CopyBuffer(handleEMA50, 0, 1, 1, buf50) <= 0) return 0; - if(CopyBuffer(handleEMA200, 0, 1, 1, buf200) <= 0) return 0; - double ema50 = buf50[0]; - double ema200 = buf200[0]; - - if(ema50 == 0 || ema200 == 0) return 0; - - double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); - double diff = MathAbs(ema50 - ema200); - double thresh = 0.001 * price; // nếu 2 EMA quá gần nhau thì bỏ qua - - if(diff < thresh) return 0; // EMA chồng nhau -> không rõ xu hướng - if(ema50 > ema200) return 1; // EMA nhanh trên EMA chậm -> uptrend - if(ema50 < ema200) return -1; // EMA nhanh dưới EMA chậm -> downtrend - return 0; -} - -// ---- Đặt lệnh thị trường ---- -bool PlaceMarketOrder(bool isBuy, double lots, double sl, double tp) { - trade.SetExpertMagicNumber(20251008); - trade.SetDeviationInPoints(Slippage); - - bool ok = false; - if(isBuy) - ok = trade.Buy(lots, NULL, 0, sl, tp, NULL); - else - ok = trade.Sell(lots, NULL, 0, sl, tp, NULL); - - if(!ok) { - Print("Đặt lệnh thất bại: ", trade.ResultRetcode(), " - ", trade.ResultRetcodeDescription()); - return false; - } - - return true; -} - -// ================== VÒNG LẶP CHÍNH ================================ -void OnTick() { - static datetime lastEntryTime = 0; - datetime t = iTime(_Symbol, EntryTF, 0); - - // Đảm bảo chỉ chạy 1 lần mỗi cây nến mới - if(t == lastEntryTime) return; - lastEntryTime = t; - - // Giới hạn số lệnh mở - if(CountOpenPositionsSymbol() >= MaxOpenPositions) return; - - // Kiểm tra hướng xu hướng từ EMA - int filter = EMAFilter(); - if(filter == 0) return; // nếu chưa rõ xu hướng thì bỏ qua - - double level = 0.0; - bool buySignal = false; - bool sellSignal = false; - - // --- TÌM TÍN HIỆU MUA --- - if(filter == 1 && DetectDoubleBottom(EntryTF, 40, DoubleTolerancePoints, level)) { - // Nếu thấy mô hình 2 đáy + nến nhấn chìm tăng hoặc giá vượt qua level -> BUY - if(IsBullishEngulfing(EntryTF) || iClose(_Symbol, EntryTF, 0) > level) - buySignal = true; - } - - // --- TÌM TÍN HIỆU BÁN --- - if(filter == -1 && DetectDoubleTop(EntryTF, 40, DoubleTolerancePoints, level)) { - // Nếu thấy mô hình 2 đỉnh + nến nhấn chìm giảm hoặc giá cắt xuống level -> SELL - if(IsBearishEngulfing(EntryTF) || iClose(_Symbol, EntryTF, 0) < level) - sellSignal = true; - } - - // --- Kiểm tra chạm EMA như hỗ trợ/kháng cự phụ --- - double ema50_trend = iMA(_Symbol, TrendTF, EMA_Fast, 0, MODE_EMA, PRICE_CLOSE); - - if(filter == 1 && !buySignal) { - double lowTouch = iLow(_Symbol, EntryTF, 1); - // Nếu nến vừa rồi chạm EMA50 (hỗ trợ) và có nhấn chìm tăng -> BUY - if(lowTouch <= ema50_trend && IsBullishEngulfing(EntryTF)) - buySignal = true; - } - - if(filter == -1 && !sellSignal) { - double highTouch = iHigh(_Symbol, EntryTF, 1); - // Nếu nến vừa rồi chạm EMA50 (kháng cự) và có nhấn chìm giảm -> SELL - if(highTouch >= ema50_trend && IsBearishEngulfing(EntryTF)) - sellSignal = true; - } - - // Không có tín hiệu nào -> thoát - if(!buySignal && !sellSignal) return; - - // --- TÍNH TOÁN ENTRY, SL, TP --- - double entryPrice = (buySignal ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) - : SymbolInfoDouble(_Symbol, SYMBOL_BID)); - double slPrice = 0.0; - double tpPrice = 0.0; - double stopLossPoints = SL_Pips_Default; - - // Nếu có level từ mô hình (double top/bottom) - if(level > 0) { - if(buySignal) { - slPrice = level - 5*_Point; // SL thấp hơn đáy 5 points - stopLossPoints = MathAbs(entryPrice - slPrice)/_Point; - } - if(sellSignal) { - slPrice = level + 5*_Point; // SL cao hơn đỉnh 5 points - stopLossPoints = MathAbs(entryPrice - slPrice)/_Point; - } - } else { - // Nếu không có mô hình -> dùng SL mặc định - if(buySignal) slPrice = entryPrice - SL_Pips_Default*_Point; - if(sellSignal) slPrice = entryPrice + SL_Pips_Default*_Point; - stopLossPoints = SL_Pips_Default; - } - - // Tính khối lượng phù hợp với rủi ro - double lots = CalculateLotByRisk(RiskPercent, stopLossPoints); - - // Nếu có TP multiplier -> tính TP - if(TP_Multiplier > 0) { - double riskPriceDiff = MathAbs(entryPrice - slPrice); - if(buySignal) - tpPrice = entryPrice + TP_Multiplier * riskPriceDiff; - else - tpPrice = entryPrice - TP_Multiplier * riskPriceDiff; - } - - // Kiểm tra lại số lệnh mở (phòng trường hợp vừa mở xong) - if(CountOpenPositionsSymbol() >= MaxOpenPositions) return; - - // Đặt lệnh BUY hoặc SELL - bool placed = false; - if(buySignal) - placed = PlaceMarketOrder(true, lots, slPrice, tpPrice); - else if(sellSignal) - placed = PlaceMarketOrder(false, lots, slPrice, tpPrice); - - if(placed) - PrintFormat("Đặt lệnh %s lots=%.2f SL=%.5f TP=%.5f", - (buySignal?"BUY":"SELL"), lots, slPrice, tpPrice); -} - -// ================== KHỞI TẠO & KẾT THÚC =========================== -int OnInit() { - // Tạo các handle EMA để vẽ và tính toán - 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("Lỗi tạo EMA handle. Mã lỗi: ", GetLastError()); - return(INIT_FAILED); - } - - // Nếu bật hiển thị -> vẽ lên biểu đồ - if(VisualizeEMAs) { - bool ok1 = ChartIndicatorAdd(0, 0, handleEMA50); - bool ok2 = ChartIndicatorAdd(0, 0, handleEMA200); - - if(!ok1 || !ok2) Print("Không thể vẽ EMA lên chart. Mã lỗi: ", GetLastError()); - } - - return(INIT_SUCCEEDED); -} - -void OnDeinit(const int reason) -{ - if(handleEMA50 != INVALID_HANDLE) IndicatorRelease(handleEMA50); - if(handleEMA200 != INVALID_HANDLE) IndicatorRelease(handleEMA200); -} diff --git a/Experts/EA_ICT.mq5 b/Experts/ICT.mq5 similarity index 99% rename from Experts/EA_ICT.mq5 rename to Experts/ICT.mq5 index 3aea03c..3edeaaf 100644 --- a/Experts/EA_ICT.mq5 +++ b/Experts/ICT.mq5 @@ -153,6 +153,11 @@ string BOS_Names[3][2]; // tên objects (composite) cho mỗi store entry int BOS_Count[3] = {0,0,0}; // số BOS hiện có cho mỗi slot (0..2) bool BOS_HaveZone[3][2]; // flag có zone hay không +input int NYStartHourVN = 19; +input int NYEndHourVN = 23; +input int LondonStartHourVN = 14; +input int LondonEndHourVN = 18; + void UpdateMTFFVGTouched(string symbol) { if(MTF_FVG_count <= 0) return; @@ -2447,8 +2452,44 @@ void MoveStoplossAdvanced() } } -void OnTick() +bool IsEntryTimeAllowed() { + datetime now = TimeCurrent(); + MqlDateTime t; + TimeToStruct(now, t); + + int hour = t.hour; + + // ===== LONDON ===== + if(hour >= LondonStartHourVN && hour < LondonEndHourVN) + return true; + + // ===== NEW YORK ===== + if(hour >= NYStartHourVN && hour < NYEndHourVN) + return true; + + return false; +} + +bool IsAllowedToTrade() +{ + if(!IsEntryTimeAllowed()) + return false; + + // if(EnableNewsFilter && + // IsHighImpactNewsNear(_Symbol, + // NewsBlockBeforeMin, + // NewsBlockAfterMin)) + return false; + + return true; +} + + +void OnTick() { + if(!IsAllowedToTrade()) + return; + string sym = Symbol(); CancelExpiredLimitOrder(); diff --git a/Experts/testMovingAverageEA.mq5 b/Experts/testMovingAverageEA.mq5 deleted file mode 100644 index 8ed41e8..0000000 --- a/Experts/testMovingAverageEA.mq5 +++ /dev/null @@ -1,165 +0,0 @@ -//+------------------------------------------------------------------+ -//| testMovingAverageEA.mq5 | -//| Copyright 2025, MetaQuotes Ltd. | -//| https://www.mql5.com | -//+------------------------------------------------------------------+ -#property copyright "Copyright 2025, MetaQuotes Ltd." -#property link "https://www.mql5.com" -#property version "1.00" -//+------------------------------------------------------------------+ -//| Include | -//+------------------------------------------------------------------+ -#include -//--- available signals -#include -//--- available trailing -#include -//--- available money management -#include -//+------------------------------------------------------------------+ -//| Inputs | -//+------------------------------------------------------------------+ -//--- inputs for expert -input string Expert_Title ="testMovingAverageEA"; // Document name -ulong Expert_MagicNumber =1338235432; // -bool Expert_EveryTick =false; // -//--- inputs for main signal -input int Signal_ThresholdOpen =10; // Signal threshold value to open [0...100] -input int Signal_ThresholdClose=10; // Signal threshold value to close [0...100] -input double Signal_PriceLevel =0.0; // Price level to execute a deal -input double Signal_StopLevel =50.0; // Stop Loss level (in points) -input double Signal_TakeLevel =50.0; // Take Profit level (in points) -input int Signal_Expiration =4; // Expiration of pending orders (in bars) -input double Signal_AC_Weight =1.0; // Accelerator Oscillator Weight [0...1.0] -//--- inputs for money -input double Money_FixRisk_Percent=10.0; // Risk percentage -//+------------------------------------------------------------------+ -//| Global expert object | -//+------------------------------------------------------------------+ -CExpert ExtExpert; -//+------------------------------------------------------------------+ -//| Initialization function of the expert | -//+------------------------------------------------------------------+ -int OnInit() - { -//--- Initializing expert - if(!ExtExpert.Init(Symbol(),Period(),Expert_EveryTick,Expert_MagicNumber)) - { - //--- failed - printf(__FUNCTION__+": error initializing expert"); - ExtExpert.Deinit(); - return(INIT_FAILED); - } -//--- Creating signal - CExpertSignal *signal=new CExpertSignal; - if(signal==NULL) - { - //--- failed - printf(__FUNCTION__+": error creating signal"); - ExtExpert.Deinit(); - return(INIT_FAILED); - } -//--- - ExtExpert.InitSignal(signal); - signal.ThresholdOpen(Signal_ThresholdOpen); - signal.ThresholdClose(Signal_ThresholdClose); - signal.PriceLevel(Signal_PriceLevel); - signal.StopLevel(Signal_StopLevel); - signal.TakeLevel(Signal_TakeLevel); - signal.Expiration(Signal_Expiration); -//--- Creating filter CSignalAC - CSignalAC *filter0=new CSignalAC; - if(filter0==NULL) - { - //--- failed - printf(__FUNCTION__+": error creating filter0"); - ExtExpert.Deinit(); - return(INIT_FAILED); - } - signal.AddFilter(filter0); -//--- Set filter parameters - filter0.Weight(Signal_AC_Weight); -//--- Creation of trailing object - CTrailingNone *trailing=new CTrailingNone; - if(trailing==NULL) - { - //--- failed - printf(__FUNCTION__+": error creating trailing"); - ExtExpert.Deinit(); - return(INIT_FAILED); - } -//--- Add trailing to expert (will be deleted automatically)) - if(!ExtExpert.InitTrailing(trailing)) - { - //--- failed - printf(__FUNCTION__+": error initializing trailing"); - ExtExpert.Deinit(); - return(INIT_FAILED); - } -//--- Set trailing parameters -//--- Creation of money object - CMoneyFixedRisk *money=new CMoneyFixedRisk; - if(money==NULL) - { - //--- failed - printf(__FUNCTION__+": error creating money"); - ExtExpert.Deinit(); - return(INIT_FAILED); - } -//--- Add money to expert (will be deleted automatically)) - if(!ExtExpert.InitMoney(money)) - { - //--- failed - printf(__FUNCTION__+": error initializing money"); - ExtExpert.Deinit(); - return(INIT_FAILED); - } -//--- Set money parameters - money.Percent(Money_FixRisk_Percent); -//--- Check all trading objects parameters - if(!ExtExpert.ValidationSettings()) - { - //--- failed - ExtExpert.Deinit(); - return(INIT_FAILED); - } -//--- Tuning of all necessary indicators - if(!ExtExpert.InitIndicators()) - { - //--- failed - printf(__FUNCTION__+": error initializing indicators"); - ExtExpert.Deinit(); - return(INIT_FAILED); - } -//--- ok - return(INIT_SUCCEEDED); - } -//+------------------------------------------------------------------+ -//| Deinitialization function of the expert | -//+------------------------------------------------------------------+ -void OnDeinit(const int reason) - { - ExtExpert.Deinit(); - } -//+------------------------------------------------------------------+ -//| "Tick" event handler function | -//+------------------------------------------------------------------+ -void OnTick() - { - ExtExpert.OnTick(); - } -//+------------------------------------------------------------------+ -//| "Trade" event handler function | -//+------------------------------------------------------------------+ -void OnTrade() - { - ExtExpert.OnTrade(); - } -//+------------------------------------------------------------------+ -//| "Timer" event handler function | -//+------------------------------------------------------------------+ -void OnTimer() - { - ExtExpert.OnTimer(); - } -//+------------------------------------------------------------------+ diff --git a/Profiles/Charts/Default/chart01.chr b/Profiles/Charts/Default/chart01.chr deleted file mode 100644 index 74818a1..0000000 Binary files a/Profiles/Charts/Default/chart01.chr and /dev/null differ diff --git a/Profiles/Charts/Default/order.wnd b/Profiles/Charts/Default/order.wnd index 0789302..9dd2f12 100644 Binary files a/Profiles/Charts/Default/order.wnd and b/Profiles/Charts/Default/order.wnd differ diff --git a/experts.dat b/experts.dat index 393b1d1..5015677 100644 Binary files a/experts.dat and b/experts.dat differ