//+------------------------------------------------------------------+ //| QuarterTheory_FIXED_V11.mq5 | //| MA 50 IS CRITICAL + Continuous Level Break/Retest | //| MA 7 Crosses + MA 50 Confirmation = Gold Standard | //+------------------------------------------------------------------+ #property copyright "Fixed System - MA 50 Critical + Break/Retest" #property version "11.00" #property strict #include CTrade Trade; //================ INPUT PARAMETERS ==================// input group "=== GENERAL ===" input int MagicNumber = 456789; input double Risk_Per_Trade = 1.5; input int Max_Simultaneous_Trades = 6; input group "=== MOVING AVERAGES ===" input int MA_1 = 7; // Fast trigger input int MA_2 = 14; input int MA_3 = 21; input int MA_4 = 50; // CRITICAL MA! input int MA_5 = 140; input int MA_6 = 230; input int MA_7 = 500; input int MA_8 = 1000; input int MA_9 = 1100; input int MA_10 = 1300; input group "=== MA 50 RULES (CRITICAL!) ===" input bool MA50_Must_Confirm = true; // MA 50 must align input bool MA50_Is_Major_Level = true; // MA 50 = support/resistance input bool Enter_On_MA50_Touch = true; // Enter when price touches MA 50 input int MA50_Touch_Buffer = 20; // Buffer for MA 50 touch input group "=== LEVEL BREAK & RETEST ===" input bool Enter_On_Level_Break = true; // Enter on level break input bool Enter_On_Level_Retest = true; // Enter on retest input int Lookback_Bars = 200; input int Level_Buffer_Points = 40; input bool Mark_Levels_Continuously = true; // Keep updating levels input int Level_Update_Minutes = 15; // Update every 15 min input group "=== RISK MANAGEMENT ===" input int Initial_SL_Points = 250; input int BreakEven_Points = 80; input bool Trail_To_MA50 = true; // Trail SL to MA 50 input group "=== TAKE PROFIT ===" input double Close_At_MA6_Percent = 15.0; // MA 230 input double Close_At_MA7_Percent = 25.0; // MA 500 input double Close_At_MA8_Percent = 25.0; // MA 1000 input double Close_At_MA9_Percent = 20.0; // MA 1100 // 15% runner input group "=== DAILY LIMITS ===" input double Max_Daily_Loss_Percent = 4.0; input double Max_Daily_Profit_Percent = 20.0; input int Max_Trades_Per_Day = 25; //================ GLOBALS ==================// double PriceLevels[]; string LevelTypes[]; double LevelPrevPrices[]; // Track if price broke level int TotalLevels = 0; int MA_Handles[10]; double MA_Current[10]; double MA_Previous[10]; struct Position { ulong ticket; double entry; double original_lot; bool is_buy; bool tp_ma6_hit; bool tp_ma7_hit; bool tp_ma8_hit; bool tp_ma9_hit; }; Position OpenPositions[]; double DailyStart = 0; int TodayTrades = 0; datetime LastDay = 0; datetime LastLevelUpdate = 0; //+------------------------------------------------------------------+ int OnInit() { Print("========================================"); Print("FIXED v11.0 - MA 50 CRITICAL"); Print("Break & Retest System"); Print("========================================"); Trade.SetExpertMagicNumber(MagicNumber); Trade.SetDeviationInPoints(50); int periods[10] = {MA_1, MA_2, MA_3, MA_4, MA_5, MA_6, MA_7, MA_8, MA_9, MA_10}; for(int i=0; i<10; i++) { MA_Handles[i] = iMA(_Symbol, PERIOD_CURRENT, periods[i], 0, MODE_EMA, PRICE_CLOSE); if(MA_Handles[i] == INVALID_HANDLE) { Print("ERROR: Failed to create MA ", periods[i]); return INIT_FAILED; } } Print("MA 50 (index 3) is CRITICAL confirmation"); CalculateAndMarkLevels(); DailyStart = AccountInfoDouble(ACCOUNT_BALANCE); LastLevelUpdate = TimeCurrent(); return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ void OnDeinit(const int reason) { for(int i=0; i<10; i++) if(MA_Handles[i] != INVALID_HANDLE) IndicatorRelease(MA_Handles[i]); ObjectsDeleteAll(0, "Level_"); ObjectsDeleteAll(0, "Arrow_"); ObjectsDeleteAll(0, "MA50_"); Print("EA Stopped"); } //+------------------------------------------------------------------+ //| CALCULATE AND MARK LEVELS CONTINUOUSLY //+------------------------------------------------------------------+ void CalculateAndMarkLevels() { // Clear old data ArrayResize(PriceLevels, 0); ArrayResize(LevelTypes, 0); ArrayResize(LevelPrevPrices, 0); TotalLevels = 0; // Find ATH/ATL double high = iHigh(_Symbol, PERIOD_CURRENT, 0); double low = iLow(_Symbol, PERIOD_CURRENT, 0); for(int i=1; i<=Lookback_Bars; i++) { double h = iHigh(_Symbol, PERIOD_CURRENT, i); double l = iLow(_Symbol, PERIOD_CURRENT, i); if(h > high) high = h; if(l < low) low = l; } double range = high - low; // Add levels AddLevel(low, "FIB_0.0", iClose(_Symbol, PERIOD_CURRENT, 1)); AddLevel(low + range * 0.236, "FIB_0.236", iClose(_Symbol, PERIOD_CURRENT, 1)); AddLevel(low + range * 0.382, "FIB_0.382", iClose(_Symbol, PERIOD_CURRENT, 1)); AddLevel(low + range * 0.5, "FIB_0.5", iClose(_Symbol, PERIOD_CURRENT, 1)); AddLevel(low + range * 0.618, "FIB_0.618", iClose(_Symbol, PERIOD_CURRENT, 1)); AddLevel(low + range * 0.786, "FIB_0.786", iClose(_Symbol, PERIOD_CURRENT, 1)); AddLevel(high, "FIB_1.0", iClose(_Symbol, PERIOD_CURRENT, 1)); AddLevel(high + range * 0.618, "FIB_1.618", iClose(_Symbol, PERIOD_CURRENT, 1)); // Quarters AddLevel(low + range * 0.25, "QUARTER_0.25", iClose(_Symbol, PERIOD_CURRENT, 1)); AddLevel(low + range * 0.75, "QUARTER_0.75", iClose(_Symbol, PERIOD_CURRENT, 1)); // Eighths AddLevel(low + range * 0.125, "EIGHTH_0.125", iClose(_Symbol, PERIOD_CURRENT, 1)); AddLevel(low + range * 0.375, "EIGHTH_0.375", iClose(_Symbol, PERIOD_CURRENT, 1)); AddLevel(low + range * 0.625, "EIGHTH_0.625", iClose(_Symbol, PERIOD_CURRENT, 1)); AddLevel(low + range * 0.875, "EIGHTH_0.875", iClose(_Symbol, PERIOD_CURRENT, 1)); Print("Levels marked: ", TotalLevels, " | Range: ", (int)(range/_Point), " points"); DrawLevels(); } //+------------------------------------------------------------------+ void AddLevel(double price, string type, double prev_price) { int size = ArraySize(PriceLevels); ArrayResize(PriceLevels, size + 1); ArrayResize(LevelTypes, size + 1); ArrayResize(LevelPrevPrices, size + 1); PriceLevels[size] = price; LevelTypes[size] = type; LevelPrevPrices[size] = prev_price; TotalLevels++; } //+------------------------------------------------------------------+ void DrawLevels() { ObjectsDeleteAll(0, "Level_"); for(int i=0; i= 0 || StringFind(LevelTypes[i], "FIB_0.618") >= 0) { clr = clrYellow; width = 2; } else if(StringFind(LevelTypes[i], "FIB") >= 0) { clr = clrDodgerBlue; width = 1; } else if(StringFind(LevelTypes[i], "QUARTER") >= 0) { clr = clrLime; width = 1; } ObjectCreate(0, name, OBJ_HLINE, 0, 0, PriceLevels[i]); ObjectSetInteger(0, name, OBJPROP_COLOR, clr); ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DOT); ObjectSetInteger(0, name, OBJPROP_WIDTH, width); ObjectSetInteger(0, name, OBJPROP_BACK, true); ObjectSetString(0, name, OBJPROP_TEXT, LevelTypes[i]); } // Draw MA 50 as special level UpdateMAs(); string ma50_name = "MA50_Line"; ObjectCreate(0, ma50_name, OBJ_HLINE, 0, 0, MA_Current[3]); ObjectSetInteger(0, ma50_name, OBJPROP_COLOR, clrOrange); ObjectSetInteger(0, ma50_name, OBJPROP_STYLE, STYLE_SOLID); ObjectSetInteger(0, ma50_name, OBJPROP_WIDTH, 2); ObjectSetString(0, ma50_name, OBJPROP_TEXT, "MA 50 - CRITICAL"); } //+------------------------------------------------------------------+ void UpdateMAs() { for(int i=0; i<10; i++) { double curr[1], prev[1]; if(CopyBuffer(MA_Handles[i], 0, 0, 1, curr) > 0) MA_Current[i] = curr[0]; else MA_Current[i] = 0; if(CopyBuffer(MA_Handles[i], 0, 1, 1, prev) > 0) MA_Previous[i] = prev[0]; else MA_Previous[i] = 0; } } //+------------------------------------------------------------------+ //| CHECK MA 50 CONFIRMATION //+------------------------------------------------------------------+ bool MA50_Confirms_Direction(bool check_bullish) { if(!MA50_Must_Confirm) return true; // MA 50 must be aligned with direction if(check_bullish) { // For bullish: MA 7 should be above MA 50 return MA_Current[0] > MA_Current[3]; } else { // For bearish: MA 7 should be below MA 50 return MA_Current[0] < MA_Current[3]; } } //+------------------------------------------------------------------+ //| CHECK IF PRICE TOUCHING MA 50 //+------------------------------------------------------------------+ bool IsPriceTouchingMA50(double price, bool &bullish_touch, bool &bearish_touch) { double buffer = MA50_Touch_Buffer * _Point; double ma50 = MA_Current[3]; bullish_touch = false; bearish_touch = false; if(MathAbs(price - ma50) <= buffer) { // Check if approaching from below (bullish) or above (bearish) double prev_price = iClose(_Symbol, PERIOD_CURRENT, 1); if(prev_price < ma50 && price >= ma50 - buffer) bullish_touch = true; else if(prev_price > ma50 && price <= ma50 + buffer) bearish_touch = true; return true; } return false; } //+------------------------------------------------------------------+ //| DETECT LEVEL BREAK //+------------------------------------------------------------------+ bool DetectLevelBreak(double current_price, double prev_price, bool &bullish_break, bool &bearish_break, int &level_index) { bullish_break = false; bearish_break = false; level_index = -1; for(int i=0; i level) { bullish_break = true; level_index = i; LevelPrevPrices[i] = current_price; // Update Print("LEVEL BREAK UP: ", LevelTypes[i], " @ ", level); return true; } // Bearish break: previous above, current below if(prev_price > level && current_price < level) { bearish_break = true; level_index = i; LevelPrevPrices[i] = current_price; // Update Print("LEVEL BREAK DOWN: ", LevelTypes[i], " @ ", level); return true; } } return false; } //+------------------------------------------------------------------+ //| DETECT LEVEL RETEST //+------------------------------------------------------------------+ bool DetectLevelRetest(double current_price, bool &bullish_retest, bool &bearish_retest, int &level_index) { bullish_retest = false; bearish_retest = false; level_index = -1; double buffer = Level_Buffer_Points * _Point; for(int i=0; i level + buffer && current_price <= level + buffer && current_price >= level - buffer) { bullish_retest = true; level_index = i; Print("LEVEL RETEST (Bull): ", LevelTypes[i], " @ ", level); return true; } // Bearish retest: price broke below, now retesting from below if(prev_level_price < level - buffer && current_price >= level - buffer && current_price <= level + buffer) { bearish_retest = true; level_index = i; Print("LEVEL RETEST (Bear): ", LevelTypes[i], " @ ", level); return true; } } return false; } //+------------------------------------------------------------------+ //| CHECK MA 7 CROSSES //+------------------------------------------------------------------+ bool MA7_Crossed_Up() { // Check if MA 7 recently crossed above any MA for(int i=1; i<5; i++) // Check 14, 21, 50, 140 { if(MA_Previous[0] <= MA_Previous[i] && MA_Current[0] > MA_Current[i]) { Print("MA 7 crossed UP through MA ", GetMAPeriod(i)); return true; } } return false; } bool MA7_Crossed_Down() { // Check if MA 7 recently crossed below any MA for(int i=1; i<5; i++) // Check 14, 21, 50, 140 { if(MA_Previous[0] >= MA_Previous[i] && MA_Current[0] < MA_Current[i]) { Print("MA 7 crossed DOWN through MA ", GetMAPeriod(i)); return true; } } return false; } int GetMAPeriod(int index) { int periods[10] = {MA_1, MA_2, MA_3, MA_4, MA_5, MA_6, MA_7, MA_8, MA_9, MA_10}; if(index >= 0 && index < 10) return periods[index]; return 0; } //+------------------------------------------------------------------+ double GetLotSize(int sl_points) { double risk = AccountInfoDouble(ACCOUNT_BALANCE) * Risk_Per_Trade / 100.0; double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE); double lot = risk / ((sl_points * _Point / tickSize) * tickValue); double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN); double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX); double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP); lot = MathMax(lot, minLot); lot = MathMin(lot, maxLot); lot = NormalizeDouble(lot / step, 0) * step; return lot; } //+------------------------------------------------------------------+ bool CheckLimits() { MqlDateTime dt; TimeCurrent(dt); dt.hour = 0; dt.min = 0; dt.sec = 0; datetime today = StructToTime(dt); if(today != LastDay) { DailyStart = AccountInfoDouble(ACCOUNT_BALANCE); TodayTrades = 0; LastDay = today; } if(TodayTrades >= Max_Trades_Per_Day) return false; double balance = AccountInfoDouble(ACCOUNT_BALANCE); double pl = ((balance - DailyStart) / DailyStart) * 100.0; if(pl <= -Max_Daily_Loss_Percent || pl >= Max_Daily_Profit_Percent) return false; return true; } //+------------------------------------------------------------------+ void OpenTrade(bool buy, double price, string reason) { double lot = GetLotSize(Initial_SL_Points); if(lot < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)) return; double sl = buy ? price - Initial_SL_Points * _Point : price + Initial_SL_Points * _Point; bool result = false; if(buy) result = Trade.Buy(lot, _Symbol, price, sl, 0, reason); else result = Trade.Sell(lot, _Symbol, price, sl, 0, reason); if(result) { TodayTrades++; ulong ticket = Trade.ResultOrder(); int size = ArraySize(OpenPositions); ArrayResize(OpenPositions, size + 1); OpenPositions[size].ticket = ticket; OpenPositions[size].entry = price; OpenPositions[size].original_lot = lot; OpenPositions[size].is_buy = buy; OpenPositions[size].tp_ma6_hit = false; OpenPositions[size].tp_ma7_hit = false; OpenPositions[size].tp_ma8_hit = false; OpenPositions[size].tp_ma9_hit = false; Print("========== TRADE ", TodayTrades, " =========="); Print(buy ? "BUY" : "SELL", " @ ", price); Print("Reason: ", reason); Print("MA 50: ", MA_Current[3]); Print("==================================="); // Draw arrow string arrow_name = "Arrow_" + IntegerToString(ticket); ObjectCreate(0, arrow_name, OBJ_ARROW, 0, TimeCurrent(), price); ObjectSetInteger(0, arrow_name, OBJPROP_COLOR, buy ? clrLime : clrRed); ObjectSetInteger(0, arrow_name, OBJPROP_ARROWCODE, buy ? 233 : 234); ObjectSetInteger(0, arrow_name, OBJPROP_WIDTH, 3); } } //+------------------------------------------------------------------+ void ManagePositions() { UpdateMAs(); for(int i=PositionsTotal()-1; i>=0; i--) { ulong ticket = PositionGetTicket(i); if(ticket == 0) continue; if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue; if(PositionGetInteger(POSITION_MAGIC) != MagicNumber) continue; int idx = -1; for(int j=0; j= BreakEven_Points) { if((is_buy && sl < entry) || (!is_buy && sl > entry)) { Trade.PositionModify(ticket, entry, 0); } } // Trail to MA 50 if(Trail_To_MA50 && profit_points >= 100) { double ma50 = MA_Current[3]; if(is_buy && ma50 > sl + 20 * _Point) { Trade.PositionModify(ticket, ma50, 0); Print("SL → MA 50: ", ma50); } else if(!is_buy && ma50 < sl - 20 * _Point) { Trade.PositionModify(ticket, ma50, 0); Print("SL → MA 50: ", ma50); } } double lot = PositionGetDouble(POSITION_VOLUME); // Partial TPs if(!OpenPositions[idx].tp_ma6_hit) { bool hit = is_buy ? (current >= MA_Current[5]) : (current <= MA_Current[5]); if(hit) { double close_size = NormalizeDouble(OpenPositions[idx].original_lot * Close_At_MA6_Percent / 100.0, 2); if(close_size > 0 && close_size <= lot) { Trade.PositionClosePartial(ticket, close_size); OpenPositions[idx].tp_ma6_hit = true; Print("TP: MA 230"); } } } if(!OpenPositions[idx].tp_ma7_hit) { bool hit = is_buy ? (current >= MA_Current[6]) : (current <= MA_Current[6]); if(hit) { double close_size = NormalizeDouble(OpenPositions[idx].original_lot * Close_At_MA7_Percent / 100.0, 2); if(close_size > 0 && close_size <= lot) { Trade.PositionClosePartial(ticket, close_size); OpenPositions[idx].tp_ma7_hit = true; Print("TP: MA 500"); } } } if(!OpenPositions[idx].tp_ma8_hit) { bool hit = is_buy ? (current >= MA_Current[7]) : (current <= MA_Current[7]); if(hit) { double close_size = NormalizeDouble(OpenPositions[idx].original_lot * Close_At_MA8_Percent / 100.0, 2); if(close_size > 0 && close_size <= lot) { Trade.PositionClosePartial(ticket, close_size); OpenPositions[idx].tp_ma8_hit = true; Print("TP: MA 1000"); } } } if(!OpenPositions[idx].tp_ma9_hit) { bool hit = is_buy ? (current >= MA_Current[8]) : (current <= MA_Current[8]); if(hit) { double close_size = NormalizeDouble(OpenPositions[idx].original_lot * Close_At_MA9_Percent / 100.0, 2); if(close_size > 0 && close_size <= lot) { Trade.PositionClosePartial(ticket, close_size); OpenPositions[idx].tp_ma9_hit = true; Print("TP: MA 1100"); } } } } } //+------------------------------------------------------------------+ void OnTick() { // Update levels continuously if(Mark_Levels_Continuously) { if(TimeCurrent() - LastLevelUpdate > Level_Update_Minutes * 60) { CalculateAndMarkLevels(); LastLevelUpdate = TimeCurrent(); } } ManagePositions(); if(!CheckLimits()) return; int open = 0; for(int i=0; i= Max_Simultaneous_Trades) return; UpdateMAs(); double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double current = (bid + ask) / 2; double previous = iClose(_Symbol, PERIOD_CURRENT, 1); // Check MA 7 crosses bool ma7_up = MA7_Crossed_Up(); bool ma7_down = MA7_Crossed_Down(); // Check MA 50 confirmation bool ma50_bull = MA50_Confirms_Direction(true); bool ma50_bear = MA50_Confirms_Direction(false); // Check MA 50 touch bool bull_ma50_touch = false; bool bear_ma50_touch = false; if(Enter_On_MA50_Touch) IsPriceTouchingMA50(current, bull_ma50_touch, bear_ma50_touch); // Check level breaks bool bull_break = false; bool bear_break = false; int break_level_idx = -1; if(Enter_On_Level_Break) DetectLevelBreak(current, previous, bull_break, bear_break, break_level_idx); // Check level retests bool bull_retest = false; bool bear_retest = false; int retest_level_idx = -1; if(Enter_On_Level_Retest) DetectLevelRetest(current, bull_retest, bear_retest, retest_level_idx); // === BUY SIGNALS === bool buy_signal = false; string buy_reason = ""; // 1. MA 7 crossed up + MA 50 confirms if(ma7_up && ma50_bull) { buy_signal = true; buy_reason = "MA 7 Cross Up + MA 50 Confirms"; } // 2. Level break + MA 50 confirms if(bull_break && ma50_bull && break_level_idx >= 0) { buy_signal = true; buy_reason = "Level Break: " + LevelTypes[break_level_idx]; } // 3. Level retest + MA 50 confirms if(bull_retest && ma50_bull && retest_level_idx >= 0) { buy_signal = true; buy_reason = "Level Retest: " + LevelTypes[retest_level_idx]; } // 4. MA 50 touch + MA 7 above MA 50 if(bull_ma50_touch && ma50_bull) { buy_signal = true; buy_reason = "MA 50 Touch (CRITICAL!)"; } // === SELL SIGNALS === bool sell_signal = false; string sell_reason = ""; // 1. MA 7 crossed down + MA 50 confirms if(ma7_down && ma50_bear) { sell_signal = true; sell_reason = "MA 7 Cross Down + MA 50 Confirms"; } // 2. Level break + MA 50 confirms if(bear_break && ma50_bear && break_level_idx >= 0) { sell_signal = true; sell_reason = "Level Break: " + LevelTypes[break_level_idx]; } // 3. Level retest + MA 50 confirms if(bear_retest && ma50_bear && retest_level_idx >= 0) { sell_signal = true; sell_reason = "Level Retest: " + LevelTypes[retest_level_idx]; } // 4. MA 50 touch + MA 7 below MA 50 if(bear_ma50_touch && ma50_bear) { sell_signal = true; sell_reason = "MA 50 Touch (CRITICAL!)"; } // EXECUTE if(buy_signal) { OpenTrade(true, ask, buy_reason); } if(sell_signal) { OpenTrade(false, bid, sell_reason); } } //+------------------------------------------------------------------+