//+------------------------------------------------------------------+ //| QuarterTheory_ULTIMATE.mq5 | //| PURE BREAK & RETEST SYSTEM - ALL LAYERS | //| MAs Break Each Other + Price Levels Break + TRIX Levels Break | //+------------------------------------------------------------------+ #property copyright "Ultimate Break & Retest System" #property version "6.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 = 4; input group "=== PRICE LEVELS (Break & Retest) ===" input int Lookback_Bars = 200; input int Level_Buffer_Points = 30; input bool Show_Levels = true; input group "=== MA CROSSOVERS (Break & Retest) ===" input int MA_1 = 7; input int MA_2 = 14; input int MA_3 = 21; input int MA_4 = 50; 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 int Min_MA_Crosses_For_Entry = 1; // Min crosses to trigger input int MA_Crosses_For_Extended = 2; // Crosses for bigger TP input int MA_Crosses_For_Maximum = 3; // Crosses for max TP input group "=== TRIX LEVELS (Break & Retest) ===" input int TRIX_Period = 18; input double TRIX_Level_Spacing = 25.0; input int Min_TRIX_Breaks = 1; // Min breaks to trigger input int TRIX_Breaks_For_Extended = 2; // Breaks for bigger TP input int TRIX_Breaks_For_Maximum = 3; // Breaks for max TP input group "=== CONFIRMATION RULES ===" input bool Require_Price_Level = true; // Need price at level input bool Require_MA_Cross = true; // Need MA cross input bool Require_TRIX_Break = true; // Need TRIX break input group "=== DYNAMIC TAKE PROFIT ===" // BASE (minimum confirmations) input int BASE_TP1 = 50; input int BASE_TP2 = 100; input int BASE_TP3 = 150; input int BASE_TP4 = 250; // EXTENDED (2+ confirmations each layer) input int EXTENDED_TP1 = 75; input int EXTENDED_TP2 = 150; input int EXTENDED_TP3 = 225; input int EXTENDED_TP4 = 400; // MAXIMUM (3+ confirmations each layer) input int MAXIMUM_TP1 = 100; input int MAXIMUM_TP2 = 200; input int MAXIMUM_TP3 = 300; input int MAXIMUM_TP4 = 600; input double TP1_Close_Percent = 25.0; input double TP2_Close_Percent = 33.0; input double TP3_Close_Percent = 25.0; input group "=== RISK MANAGEMENT ===" input int Initial_SL_Points = 150; input int BreakEven_Points = 80; input int Trailing_Start = 100; input int Trailing_Step = 30; input int Trailing_Stop = 40; input group "=== DAILY LIMITS ===" input double Max_Daily_Loss_Percent = 3.0; input double Max_Daily_Profit_Percent = 10.0; input int Max_Trades_Per_Day = 12; //================ GLOBALS ==================// double PriceLevels[]; int TotalLevels = 0; int MA_Handles[10]; double MA_Current[10]; double MA_Previous[10]; int TRIX_Handle; double TRIX_Current = 0; double TRIX_Previous = 0; double TRIX_Levels[20]; bool TRIX_Level_Broken_Up[20]; bool TRIX_Level_Broken_Down[20]; struct Position { ulong ticket; double entry; double original_lot; int tp_mode; // 0=BASE, 1=EXTENDED, 2=MAXIMUM int ma_crosses; int trix_breaks; bool tp1_hit; bool tp2_hit; bool tp3_hit; }; Position OpenPositions[]; double DailyStart = 0; int TodayTrades = 0; datetime LastDay = 0; //+------------------------------------------------------------------+ int OnInit() { Print("========================================"); Print("ULTIMATE BREAK & RETEST SYSTEM v6.0"); Print("========================================"); Trade.SetExpertMagicNumber(MagicNumber); Trade.SetDeviationInPoints(50); // Initialize MAs 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: MA Handle ", i, " failed"); return INIT_FAILED; } } // Initialize TRIX TRIX_Handle = iMA(_Symbol, PERIOD_CURRENT, TRIX_Period, 0, MODE_EMA, PRICE_CLOSE); // Setup TRIX levels int idx = 0; for(double level=-100; level<=100; level+=TRIX_Level_Spacing) { TRIX_Levels[idx] = level; TRIX_Level_Broken_Up[idx] = false; TRIX_Level_Broken_Down[idx] = false; idx++; } CalculatePriceLevels(); if(Show_Levels) DrawLevels(); DailyStart = AccountInfoDouble(ACCOUNT_BALANCE); Print("Initialized | Price Levels: ", TotalLevels); Print("MA Periods: ", MA_1, ",", MA_2, ",", MA_3, ",", MA_4, ",", MA_5, ",", MA_6, ",", MA_7, ",", MA_8, ",", MA_9, ",", MA_10); return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ void OnDeinit(const int reason) { for(int i=0; i<10; i++) IndicatorRelease(MA_Handles[i]); IndicatorRelease(TRIX_Handle); ObjectsDeleteAll(0, "Level_"); Print("EA Stopped"); } //+------------------------------------------------------------------+ //| CALCULATE PRICE LEVELS (Keep dividing in half) //+------------------------------------------------------------------+ void CalculatePriceLevels() { ArrayResize(PriceLevels, 0); TotalLevels = 0; double high = iHigh(_Symbol, PERIOD_CURRENT, 1); double low = iLow(_Symbol, PERIOD_CURRENT, 1); for(int i=2; 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; // Keep dividing in half (binary division) AddLevel(low); // 0.0 AddLevel(high); // 1.0 AddLevel(low + range * 0.5); // 0.5 (half) AddLevel(low + range * 0.25); // 0.25 (quarter) AddLevel(low + range * 0.75); // 0.75 (quarter) AddLevel(low + range * 0.125); // 0.125 (eighth) AddLevel(low + range * 0.375); // 0.375 (eighth) AddLevel(low + range * 0.625); // 0.625 (eighth) AddLevel(low + range * 0.875); // 0.875 (eighth) // Fibonacci (for extra precision) AddLevel(low + range * 0.236); AddLevel(low + range * 0.382); AddLevel(low + range * 0.618); AddLevel(low + range * 0.786); AddLevel(high + range * 0.618); // Extension // Sort for(int i=0; i MA_Current[j]) crosses++; } else { // Lower MA crosses BELOW higher MA = bearish if(MA_Previous[i] >= MA_Previous[j] && MA_Current[i] < MA_Current[j]) crosses++; } } } return crosses; } //+------------------------------------------------------------------+ //| UPDATE TRIX & DETECT LEVEL BREAKS //+------------------------------------------------------------------+ int CountTRIXBreaks(bool bullish) { double buf[2]; CopyBuffer(TRIX_Handle, 0, 0, 2, buf); TRIX_Previous = TRIX_Current; TRIX_Current = ((buf[0] - buf[1]) / buf[1]) * 10000; // Scale TRIX // Detect breaks for(int i=0; i<20; i++) { double level = TRIX_Levels[i]; // Upward break if(TRIX_Previous < level && TRIX_Current >= level) TRIX_Level_Broken_Up[i] = true; // Downward break if(TRIX_Previous > level && TRIX_Current <= level) TRIX_Level_Broken_Down[i] = true; // Reset after 4 hours // (simplified - in production track break time) } // Count breaks in direction int breaks = 0; for(int i=0; i<20; i++) { if(bullish && TRIX_Level_Broken_Up[i] && TRIX_Levels[i] > 0) breaks++; if(!bullish && TRIX_Level_Broken_Down[i] && TRIX_Levels[i] < 0) breaks++; } return breaks; } //+------------------------------------------------------------------+ //| CHECK IF PRICE AT LEVEL //+------------------------------------------------------------------+ bool IsPriceAtLevel(double price) { double buffer = Level_Buffer_Points * _Point; for(int i=0; i= MA_Crosses_For_Maximum) total_strength++; else if(ma_crosses >= MA_Crosses_For_Extended) total_strength++; if(trix_breaks >= TRIX_Breaks_For_Maximum) total_strength++; else if(trix_breaks >= TRIX_Breaks_For_Extended) total_strength++; // Determine mode if(total_strength >= 2) return 2; // MAXIMUM (both strong) if(total_strength >= 1) return 1; // EXTENDED (one strong) return 0; // BASE } void GetTPTargets(int mode, int &tp1, int &tp2, int &tp3, int &tp4) { if(mode == 2) { tp1 = MAXIMUM_TP1; tp2 = MAXIMUM_TP2; tp3 = MAXIMUM_TP3; tp4 = MAXIMUM_TP4; } else if(mode == 1) { tp1 = EXTENDED_TP1; tp2 = EXTENDED_TP2; tp3 = EXTENDED_TP3; tp4 = EXTENDED_TP4; } else { tp1 = BASE_TP1; tp2 = BASE_TP2; tp3 = BASE_TP3; tp4 = BASE_TP4; } } //+------------------------------------------------------------------+ //| CALCULATE LOT SIZE //+------------------------------------------------------------------+ 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; } //+------------------------------------------------------------------+ //| CHECK DAILY LIMITS //+------------------------------------------------------------------+ 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; } //+------------------------------------------------------------------+ //| OPEN TRADE //+------------------------------------------------------------------+ void OpenTrade(bool buy, double price, int ma_crosses, int trix_breaks) { double lot = GetLotSize(Initial_SL_Points); if(lot < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)) return; int mode = DetermineTPMode(ma_crosses, trix_breaks); string mode_text = "BASE"; if(mode == 1) mode_text = "EXTENDED"; if(mode == 2) mode_text = "MAXIMUM"; double sl = buy ? price - Initial_SL_Points * _Point : price + Initial_SL_Points * _Point; string comment = "MA:" + IntegerToString(ma_crosses) + " TRIX:" + IntegerToString(trix_breaks) + " " + mode_text; bool result = false; if(buy) result = Trade.Buy(lot, _Symbol, price, sl, 0, comment); else result = Trade.Sell(lot, _Symbol, price, sl, 0, comment); 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].tp_mode = mode; OpenPositions[size].ma_crosses = ma_crosses; OpenPositions[size].trix_breaks = trix_breaks; OpenPositions[size].tp1_hit = false; OpenPositions[size].tp2_hit = false; OpenPositions[size].tp3_hit = false; Print("===== TRADE OPENED ====="); Print("Direction: ", buy ? "BUY" : "SELL"); Print("MA Crosses: ", ma_crosses); Print("TRIX Breaks: ", trix_breaks); Print("TP Mode: ", mode_text); Print("========================"); } } //+------------------------------------------------------------------+ //| MANAGE POSITIONS //+------------------------------------------------------------------+ void ManagePositions() { 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; // Find in our tracking int idx = -1; for(int j=0; j= BreakEven_Points) { if((type == POSITION_TYPE_BUY && sl < entry) || (type == POSITION_TYPE_SELL && sl > entry)) { double newSL = entry; Trade.PositionModify(ticket, newSL, 0); } } // Partial TPs int tp1, tp2, tp3, tp4; GetTPTargets(OpenPositions[idx].tp_mode, tp1, tp2, tp3, tp4); double lot = PositionGetDouble(POSITION_VOLUME); if(!OpenPositions[idx].tp1_hit && profit_points >= tp1) { double close = NormalizeDouble(OpenPositions[idx].original_lot * TP1_Close_Percent / 100, 2); if(close > 0 && close <= lot) { Trade.PositionClosePartial(ticket, close); OpenPositions[idx].tp1_hit = true; } } if(!OpenPositions[idx].tp2_hit && profit_points >= tp2) { double close = NormalizeDouble(OpenPositions[idx].original_lot * TP2_Close_Percent / 100, 2); if(close > 0 && close <= lot) { Trade.PositionClosePartial(ticket, close); OpenPositions[idx].tp2_hit = true; } } if(!OpenPositions[idx].tp3_hit && profit_points >= tp3) { double close = NormalizeDouble(OpenPositions[idx].original_lot * TP3_Close_Percent / 100, 2); if(close > 0 && close <= lot) { Trade.PositionClosePartial(ticket, close); OpenPositions[idx].tp3_hit = true; } } // Trailing if(profit_points >= Trailing_Start) { double newSL = 0; if(type == POSITION_TYPE_BUY) { newSL = current - Trailing_Stop * _Point; if(newSL > sl + Trailing_Step * _Point) Trade.PositionModify(ticket, newSL, 0); } else { newSL = current + Trailing_Stop * _Point; if(newSL < sl - Trailing_Step * _Point) Trade.PositionModify(ticket, newSL, 0); } } } } //+------------------------------------------------------------------+ //| MAIN TICK //+------------------------------------------------------------------+ void OnTick() { ManagePositions(); // Check limits if(!CheckLimits()) return; // Count open positions int open = 0; for(int i=0; i= Max_Simultaneous_Trades) return; // Recalculate levels hourly static datetime last_calc = 0; if(TimeCurrent() - last_calc > 3600) { CalculatePriceLevels(); if(Show_Levels) DrawLevels(); last_calc = TimeCurrent(); } // Get current price double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double price = (bid + ask) / 2; // CHECK ALL BREAK & RETEST CONDITIONS // 1. Price at level? bool price_at_level = IsPriceAtLevel(price); if(Require_Price_Level && !price_at_level) return; // 2. MA crosses (lower MA breaking higher MA) int ma_crosses_bull = CountMACrosses(true); int ma_crosses_bear = CountMACrosses(false); if(Require_MA_Cross && ma_crosses_bull < Min_MA_Crosses_For_Entry && ma_crosses_bear < Min_MA_Crosses_For_Entry) return; // 3. TRIX level breaks int trix_breaks_bull = CountTRIXBreaks(true); int trix_breaks_bear = CountTRIXBreaks(false); if(Require_TRIX_Break && trix_breaks_bull < Min_TRIX_Breaks && trix_breaks_bear < Min_TRIX_Breaks) return; // ENTRY LOGIC // BUY: Lower MAs breaking above higher MAs + TRIX breaking up if(ma_crosses_bull >= Min_MA_Crosses_For_Entry && trix_breaks_bull >= Min_TRIX_Breaks) { OpenTrade(true, ask, ma_crosses_bull, trix_breaks_bull); } // SELL: Lower MAs breaking below higher MAs + TRIX breaking down if(ma_crosses_bear >= Min_MA_Crosses_For_Entry && trix_breaks_bear >= Min_TRIX_Breaks) { OpenTrade(false, bid, ma_crosses_bear, trix_breaks_bear); } } //+------------------------------------------------------------------+