//+------------------------------------------------------------------+ //| QuarterTheory_VIZION_FINAL_v5.0.mq5 | //| PULLBACK DETECTION | RUNNERS PROTECTED | STOCH EXTREMES | //| Never Close Runners on Pullbacks | Only on Full Reversal | //+------------------------------------------------------------------+ #property copyright "QuarterTheory x VIZION - Final v5.0" #property version "5.00" #property strict #include CTrade Trade; //================ INPUT PARAMETERS ==================// input group "=== CORE SETTINGS ===" input int MagicNumber = 456789; input double Risk_Per_Trade = 1.2; input int Max_Trades_Per_Setup = 10; input int Max_Total_Trades = 100; input int Min_Runners_To_Keep = 4; input group "=== MARKET MODE SYSTEM ===" input bool Use_Market_Mode_Filter = true; input int Mode_Confirmation_Bars = 2; input double Chop_ATR_Threshold = 0.5; input double Range_Price_Threshold = 0.3; input group "=== REVERSAL CONFIRMATION ===" input bool Only_Close_On_Full_Reversal = true; // Protect runners from pullbacks input int Reversal_Confirmation_Bars = 3; // Bars needed for full reversal input group "=== MA SYSTEM ===" 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 MA_Touch_Buffer = 100; input group "=== STOCHASTIC ===" input int Stoch_K_Period = 5; input int Stoch_D_Period = 3; input int Stoch_Slowing = 3; input double Stoch_Extreme_High = 85.0; // Extreme overbought input double Stoch_Extreme_Low = 15.0; // Extreme oversold input double Stoch_High = 70.0; input double Stoch_Low = 30.0; input group "=== MFIB SYSTEM ===" input int MFIB_Lookback = 500; input group "=== FIBONACCI ===" input int Lookback_Bars = 200; input bool Show_Levels = true; input group "=== 300 RULE EXIT SYSTEM ===" input int Initial_SL_Points = 300; input int BreakEven_Points = 300; input int Trailing_Distance_Points = 300; input int TP_Points = 1500; input int Partial_TP_Points = 900; input double Partial_TP_Percent = 33.0; //================ ENUMS ==================// enum MARKET_MODE { MODE_STRONG_BULL_TREND, MODE_BULL_TREND, MODE_BEAR_TREND, MODE_STRONG_BEAR_TREND, MODE_CHOPPY, MODE_RANGING, MODE_TRANSITIONAL }; enum PRICE_STATE { STATE_TREND_CONTINUATION, // Clean trend STATE_PULLBACK, // Healthy pullback (7 dip, 14/21 hold) STATE_RETRACEMENT, // Deeper retracement (7 crosses 14, but 21/50 hold) STATE_REVERSAL_FORMING, // Early reversal signs (50 pressure) STATE_FULL_REVERSAL, // Confirmed reversal (50 broken, trend changed) STATE_CONSOLIDATION, STATE_UNKNOWN }; enum SETUP_TYPE { SETUP_MA14_CROSS = 1, SETUP_MA50_BOUNCE = 2, SETUP_MA140_BOUNCE = 3, SETUP_MA230_BOUNCE = 4, SETUP_MA500_TOUCH = 5, SETUP_FIB_BREAK = 6, SETUP_FIB_RECLAIM = 7, SETUP_FIB_REJECT = 8, SETUP_MAGNET_WALK = 9, SETUP_STAIRCASE_ADV = 10, SETUP_CTRL_PULLBACK = 11, SETUP_TF_RESET = 12, SETUP_MFIB_LADDER = 13, SETUP_MFIB_PRESS = 14, SETUP_MEAN_REV = 15, SETUP_RANGE_ENGINE = 16 }; //================ GLOBALS ==================// int Stoch_Handle, ATR_Handle, ADX_Handle; double Stoch_K_Current = 0, Stoch_K_Previous = 0, Stoch_K_Prev2 = 0; double Stoch_D_Current = 0; double Current_ATR = 0; double Current_ADX = 0; double PriceLevels[7]; int MA_Handles[10]; double MA_Current[10]; double MA_Previous[10]; double MA_Prev2[10]; double MFIB_High, MFIB_Low; double MFIB_Level_236, MFIB_Level_382, MFIB_Level_050; double MFIB_Level_618, MFIB_Level_786; MARKET_MODE Current_Mode = MODE_TRANSITIONAL; MARKET_MODE Previous_Mode = MODE_TRANSITIONAL; PRICE_STATE Current_State = STATE_UNKNOWN; int Mode_Confirmation_Count = 0; int Reversal_Confirm_Counter = 0; // Warning flags bool MA7_Cross_14_Warning = false; bool MA7_Cross_21_Warning = false; bool MA50_Break_Warning = false; bool Fib_Reject_Warning = false; bool MA_Reject_Warning = false; bool Stoch_Extreme_Warning = false; bool Pullback_Warning = false; bool Retracement_Warning = false; struct Position { ulong ticket; double entry; double original_lot; bool is_buy; bool partial_tp_hit; bool be_set; bool trailing_active; bool is_runner; SETUP_TYPE setup_type; string setup_name; MARKET_MODE entry_mode; double distance_from_current; }; Position OpenPositions[]; int TodayTrades = 0; int BuyTrades = 0; int SellTrades = 0; int ClosedByReversal = 0; int SetupCount[17]; datetime LastEntryTime[17]; //+------------------------------------------------------------------+ int OnInit() { Print("========================================"); Print("FINAL SYSTEM v5.0"); Print("PULLBACK DETECTION | STOCH EXTREMES"); Print("RUNNERS PROTECTED FROM PULLBACKS"); Print("========================================"); Trade.SetExpertMagicNumber(MagicNumber); Trade.SetDeviationInPoints(50); Trade.SetTypeFilling(ORDER_FILLING_FOK); Stoch_Handle = iStochastic(_Symbol, PERIOD_CURRENT, Stoch_K_Period, Stoch_D_Period, Stoch_Slowing, MODE_SMA, STO_LOWHIGH); ATR_Handle = iATR(_Symbol, PERIOD_CURRENT, 14); ADX_Handle = iADX(_Symbol, PERIOD_CURRENT, 14); 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); } ArrayInitialize(SetupCount, 0); ArrayInitialize(LastEntryTime, 0); CalculateLevels(); if(Show_Levels) DrawLevels(); Print("Stoch Extremes: ", Stoch_Extreme_Low, " / ", Stoch_Extreme_High); Print("Runners: ", Min_Runners_To_Keep, " protected from pullbacks"); 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]); if(Stoch_Handle != INVALID_HANDLE) IndicatorRelease(Stoch_Handle); if(ATR_Handle != INVALID_HANDLE) IndicatorRelease(ATR_Handle); if(ADX_Handle != INVALID_HANDLE) IndicatorRelease(ADX_Handle); ObjectsDeleteAll(0, "Level_"); ObjectsDeleteAll(0, "ModeLabel"); ObjectsDeleteAll(0, "StateLabel"); ObjectsDeleteAll(0, "WarningLabel"); Print("Final: B:", BuyTrades, " | S:", SellTrades, " | Reversed:", ClosedByReversal); } //+------------------------------------------------------------------+ void CalculateLevels() { 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; PriceLevels[0] = low; PriceLevels[1] = low + range * 0.236; PriceLevels[2] = low + range * 0.382; PriceLevels[3] = low + range * 0.5; PriceLevels[4] = low + range * 0.618; PriceLevels[5] = low + range * 0.786; PriceLevels[6] = high; MFIB_High = high; MFIB_Low = low; MFIB_Level_236 = low + range * 0.236; MFIB_Level_382 = low + range * 0.382; MFIB_Level_050 = low + range * 0.5; MFIB_Level_618 = low + range * 0.618; MFIB_Level_786 = low + range * 0.786; } void DrawLevels() { ObjectsDeleteAll(0, "Level_"); color level_colors[7] = {clrRed, clrOrange, clrYellow, clrLime, clrCyan, clrBlue, clrMagenta}; for(int i=0; i<7; i++) { string name = "Level_" + IntegerToString(i); ObjectCreate(0, name, OBJ_HLINE, 0, 0, PriceLevels[i]); ObjectSetInteger(0, name, OBJPROP_COLOR, level_colors[i]); ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID); ObjectSetInteger(0, name, OBJPROP_WIDTH, 2); } } //+------------------------------------------------------------------+ void DetectWarnings() { double current = SymbolInfoDouble(_Symbol, SYMBOL_BID); double buffer = MA_Touch_Buffer * _Point; // Reset warnings MA7_Cross_14_Warning = false; MA7_Cross_21_Warning = false; MA50_Break_Warning = false; Fib_Reject_Warning = false; MA_Reject_Warning = false; Stoch_Extreme_Warning = false; Pullback_Warning = false; Retracement_Warning = false; // 1. STOCH EXTREME LEVELS (15/85) if(Stoch_K_Current <= Stoch_Extreme_Low || Stoch_K_Current >= Stoch_Extreme_High) { Stoch_Extreme_Warning = true; if(Stoch_K_Current <= Stoch_Extreme_Low) Print("📊 STOCH EXTREME LOW: ", DoubleToString(Stoch_K_Current, 1), " - Pullback/Reversal"); else Print("📊 STOCH EXTREME HIGH: ", DoubleToString(Stoch_K_Current, 1), " - Pullback/Reversal"); } // 2. MA7 x MA14 CROSS (Early warning) bool ma7_crossed_14_down = (MA_Previous[0] > MA_Previous[1]) && (MA_Current[0] <= MA_Current[1]); bool ma7_crossed_14_up = (MA_Previous[0] < MA_Previous[1]) && (MA_Current[0] >= MA_Current[1]); if(ma7_crossed_14_down || ma7_crossed_14_up) { MA7_Cross_14_Warning = true; Retracement_Warning = true; Print("⚠️ MA7 x MA14: ", ma7_crossed_14_down ? "BEAR RETRACEMENT" : "BULL RETRACEMENT"); } // 3. MA7 x MA21 CROSS (Deeper retracement) bool ma7_crossed_21_down = (MA_Previous[0] > MA_Previous[2]) && (MA_Current[0] <= MA_Current[2]); bool ma7_crossed_21_up = (MA_Previous[0] < MA_Previous[2]) && (MA_Current[0] >= MA_Current[2]); if(ma7_crossed_21_down || ma7_crossed_21_up) { MA7_Cross_21_Warning = true; Retracement_Warning = true; Print("⚠️ MA7 x MA21: DEEPER RETRACEMENT"); } // 4. MA50 BREAK (Reversal warning) bool ma7_broke_50_down = (MA_Previous[0] > MA_Previous[3]) && (MA_Current[0] <= MA_Current[3]); bool ma7_broke_50_up = (MA_Previous[0] < MA_Previous[3]) && (MA_Current[0] >= MA_Current[3]); if(ma7_broke_50_down || ma7_broke_50_up) { MA50_Break_Warning = true; Print("🚨 MA50 BREAK: REVERSAL FORMING"); } // 5. FIB REJECT at extremes with stoch bool at_fib = false; for(int i=1; i<6; i++) { if(MathAbs(current - PriceLevels[i]) <= buffer) { at_fib = true; break; } } if(at_fib && Stoch_Extreme_Warning) { Fib_Reject_Warning = true; Pullback_Warning = true; Print("📍 FIB REJECT + STOCH EXTREME"); } // 6. MA REJECT at key levels with stoch bool at_ma50 = MathAbs(current - MA_Current[3]) <= buffer; bool at_ma140 = MathAbs(current - MA_Current[4]) <= buffer; bool at_ma230 = MathAbs(current - MA_Current[5]) <= buffer; if((at_ma50 || at_ma140 || at_ma230) && Stoch_Extreme_Warning) { MA_Reject_Warning = true; Pullback_Warning = true; Print("🔄 MA REJECT + STOCH EXTREME"); } } //+------------------------------------------------------------------+ PRICE_STATE DeterminePriceState() { double current = SymbolInfoDouble(_Symbol, SYMBOL_BID); // Check MA structure bool ma7_above_14 = MA_Current[0] > MA_Current[1]; bool ma7_above_21 = MA_Current[0] > MA_Current[2]; bool ma7_above_50 = MA_Current[0] > MA_Current[3]; bool ma14_above_50 = MA_Current[1] > MA_Current[3]; bool ma21_above_50 = MA_Current[2] > MA_Current[3]; // Bullish structure if(Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND) { // PULLBACK: 7 dips but 14/21 hold above 50 if(!ma7_above_21 && ma14_above_50 && ma21_above_50 && Stoch_Extreme_Warning) { return STATE_PULLBACK; } // RETRACEMENT: 7 crosses 14 but 21 still above 50 if(!ma7_above_14 && !ma21_above_50 && ma14_above_50) { return STATE_RETRACEMENT; } // REVERSAL FORMING: 7 approaching 50, pressure building if(!ma7_above_50 && MA50_Break_Warning) { return STATE_REVERSAL_FORMING; } // FULL REVERSAL: 50 broken, trend changed if(!ma7_above_50 && !ma14_above_50 && !ma21_above_50) { return STATE_FULL_REVERSAL; } // CONTINUATION: Clean structure if(ma7_above_21 && ma21_above_50) { return STATE_TREND_CONTINUATION; } } // Bearish structure if(Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) { bool ma7_below_14 = MA_Current[0] < MA_Current[1]; bool ma7_below_21 = MA_Current[0] < MA_Current[2]; bool ma7_below_50 = MA_Current[0] < MA_Current[3]; bool ma14_below_50 = MA_Current[1] < MA_Current[3]; bool ma21_below_50 = MA_Current[2] < MA_Current[3]; // PULLBACK: 7 rises but 14/21 hold below 50 if(!ma7_below_21 && ma14_below_50 && ma21_below_50 && Stoch_Extreme_Warning) { return STATE_PULLBACK; } // RETRACEMENT: 7 crosses 14 but 21 still below 50 if(!ma7_below_14 && !ma21_below_50 && ma14_below_50) { return STATE_RETRACEMENT; } // REVERSAL FORMING: 7 approaching 50, pressure building if(!ma7_below_50 && MA50_Break_Warning) { return STATE_REVERSAL_FORMING; } // FULL REVERSAL: 50 broken, trend changed if(!ma7_below_50 && !ma14_below_50 && !ma21_below_50) { return STATE_FULL_REVERSAL; } // CONTINUATION: Clean structure if(ma7_below_21 && ma21_below_50) { return STATE_TREND_CONTINUATION; } } return STATE_UNKNOWN; } //+------------------------------------------------------------------+ MARKET_MODE DetermineMarketMode() { double current = SymbolInfoDouble(_Symbol, SYMBOL_BID); // Don't flip mode on pullbacks/retracements if(Current_State == STATE_PULLBACK || Current_State == STATE_RETRACEMENT) { // Keep current trend mode during pullbacks return Current_Mode; } // Only flip on FULL REVERSAL or strong signals bool force_flip = false; if(Current_State == STATE_FULL_REVERSAL) { force_flip = true; Print("🔄 FULL REVERSAL DETECTED - MODE FLIP INITIATED"); } if(MA50_Break_Warning && MA7_Cross_21_Warning && Stoch_Extreme_Warning) { force_flip = true; Print("🔄 STRONG REVERSAL SIGNALS - MODE FLIP INITIATED"); } // Standard trend detection bool ma7_above_50 = MA_Current[0] > MA_Current[3]; bool ma7_above_140 = MA_Current[0] > MA_Current[4]; bool ma7_above_230 = MA_Current[0] > MA_Current[5]; bool ma7_below_50 = MA_Current[0] < MA_Current[3]; bool ma7_below_140 = MA_Current[0] < MA_Current[4]; bool ma7_below_230 = MA_Current[0] < MA_Current[5]; bool mas_aligned_bull = (MA_Current[0] > MA_Current[1]) && (MA_Current[1] > MA_Current[2]) && (MA_Current[2] > MA_Current[3]); bool mas_aligned_bear = (MA_Current[0] < MA_Current[1]) && (MA_Current[1] < MA_Current[2]) && (MA_Current[2] < MA_Current[3]); bool above_mfib_618 = current > MFIB_Level_618; bool below_mfib_382 = current < MFIB_Level_382; bool stoch_trending_up = (Stoch_K_Current > Stoch_D_Current) && (Stoch_K_Current > 50); bool stoch_trending_down = (Stoch_K_Current < Stoch_D_Current) && (Stoch_K_Current < 50); // Chop/range detection (only if no clear trend) double recent_high = iHigh(_Symbol, PERIOD_CURRENT, 0); double recent_low = iLow(_Symbol, PERIOD_CURRENT, 0); for(int i=1; i<20; i++) { recent_high = MathMax(recent_high, iHigh(_Symbol, PERIOD_CURRENT, i)); recent_low = MathMin(recent_low, iLow(_Symbol, PERIOD_CURRENT, i)); } double range_size = (recent_high - recent_low) / current; bool is_ranging = range_size < Range_Price_Threshold; bool ma_clustered = (MathAbs(MA_Current[0] - MA_Current[3]) / Current_ATR < Chop_ATR_Threshold); bool is_choppy = (ma_clustered || Current_ADX < 15); // Stricter chop detection // Priority: Trends > Chop/Range (don't flip to chop/range during pullbacks) // Strong trends if(mas_aligned_bull && ma7_above_230 && above_mfib_618 && Current_ADX > 25) return MODE_STRONG_BULL_TREND; if(mas_aligned_bear && ma7_below_230 && below_mfib_382 && Current_ADX > 25) return MODE_STRONG_BEAR_TREND; // Regular trends (main detection) if(mas_aligned_bull && ma7_above_140 && Current_ADX > 18) return MODE_BULL_TREND; if(mas_aligned_bear && ma7_below_140 && Current_ADX > 18) return MODE_BEAR_TREND; // Weaker bull trend (still trending, just weaker) if(ma7_above_50 && Current_ADX > 15 && !is_choppy) return MODE_BULL_TREND; // Weaker bear trend if(ma7_below_50 && Current_ADX > 15 && !is_choppy) return MODE_BEAR_TREND; // Only label chop/range if truly directionless if(is_choppy && !force_flip) return MODE_CHOPPY; if(is_ranging && !mas_aligned_bull && !mas_aligned_bear && !force_flip) return MODE_RANGING; return MODE_TRANSITIONAL; } //+------------------------------------------------------------------+ void UpdateMarketMode() { // First determine state Current_State = DeterminePriceState(); MARKET_MODE detected_mode = DetermineMarketMode(); // Fast flip on full reversal int required_confirms = Mode_Confirmation_Bars; if(Current_State == STATE_FULL_REVERSAL) { required_confirms = 1; } // Don't flip mode during pullbacks/retracements if(Current_State == STATE_PULLBACK || Current_State == STATE_RETRACEMENT) { // Keep current mode, just update labels UpdateLabels(); return; } if(detected_mode != Current_Mode) { if(detected_mode == Previous_Mode) { Mode_Confirmation_Count++; if(Mode_Confirmation_Count >= required_confirms) { MARKET_MODE old_mode = Current_Mode; Current_Mode = detected_mode; Mode_Confirmation_Count = 0; Reversal_Confirm_Counter = 0; Print(">>> MODE FLIP: ", EnumToString(old_mode), " → ", EnumToString(Current_Mode)); // Only close on FULL REVERSAL if(Current_State == STATE_FULL_REVERSAL) { CloseOnFullReversal(); } } } else { Previous_Mode = detected_mode; Mode_Confirmation_Count = 1; } } else { Mode_Confirmation_Count = 0; } UpdateLabels(); } //+------------------------------------------------------------------+ void UpdateLabels() { // Mode Label ObjectDelete(0, "ModeLabel"); ObjectCreate(0, "ModeLabel", OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, "ModeLabel", OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, "ModeLabel", OBJPROP_XDISTANCE, 10); ObjectSetInteger(0, "ModeLabel", OBJPROP_YDISTANCE, 30); string mode_text = ""; color mode_color = clrYellow; switch(Current_Mode) { case MODE_STRONG_BULL_TREND: mode_text = "MODE: STRONG BULL ↑↑"; mode_color = clrLime; break; case MODE_BULL_TREND: mode_text = "MODE: BULL TREND ↑"; mode_color = clrGreenYellow; break; case MODE_BEAR_TREND: mode_text = "MODE: BEAR TREND ↓"; mode_color = clrOrange; break; case MODE_STRONG_BEAR_TREND: mode_text = "MODE: STRONG BEAR ↓↓"; mode_color = clrRed; break; case MODE_CHOPPY: mode_text = "MODE: CHOPPY ⚡"; mode_color = clrViolet; break; case MODE_RANGING: mode_text = "MODE: RANGING ↔"; mode_color = clrAqua; break; case MODE_TRANSITIONAL: mode_text = "MODE: TRANSITIONAL ~"; mode_color = clrYellow; break; } ObjectSetString(0, "ModeLabel", OBJPROP_TEXT, mode_text); ObjectSetInteger(0, "ModeLabel", OBJPROP_COLOR, mode_color); ObjectSetInteger(0, "ModeLabel", OBJPROP_FONTSIZE, 12); // State Label ObjectDelete(0, "StateLabel"); ObjectCreate(0, "StateLabel", OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, "StateLabel", OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, "StateLabel", OBJPROP_XDISTANCE, 10); ObjectSetInteger(0, "StateLabel", OBJPROP_YDISTANCE, 50); string state_text = "STATE: "; color state_color = clrWhite; switch(Current_State) { case STATE_TREND_CONTINUATION: state_text += "CONTINUATION ✓"; state_color = clrLime; break; case STATE_PULLBACK: state_text += "PULLBACK ↩ (RUNNERS SAFE)"; state_color = clrYellow; break; case STATE_RETRACEMENT: state_text += "RETRACEMENT ↪ (RUNNERS SAFE)"; state_color = clrOrange; break; case STATE_REVERSAL_FORMING: state_text += "REVERSAL FORMING ⚠"; state_color = clrOrangeRed; break; case STATE_FULL_REVERSAL: state_text += "FULL REVERSAL 🔄"; state_color = clrRed; break; case STATE_CONSOLIDATION: state_text += "CONSOLIDATION 📊"; state_color = clrAqua; break; case STATE_UNKNOWN: state_text += "UNKNOWN"; break; } ObjectSetString(0, "StateLabel", OBJPROP_TEXT, state_text); ObjectSetInteger(0, "StateLabel", OBJPROP_COLOR, state_color); ObjectSetInteger(0, "StateLabel", OBJPROP_FONTSIZE, 11); // Warning Label if(MA7_Cross_14_Warning || MA7_Cross_21_Warning || MA50_Break_Warning || Fib_Reject_Warning || MA_Reject_Warning || Stoch_Extreme_Warning) { ObjectDelete(0, "WarningLabel"); ObjectCreate(0, "WarningLabel", OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, "WarningLabel", OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, "WarningLabel", OBJPROP_XDISTANCE, 10); ObjectSetInteger(0, "WarningLabel", OBJPROP_YDISTANCE, 70); string warn_text = ""; if(Stoch_Extreme_Warning) warn_text += "📊 STOCH EXTREME | "; if(MA7_Cross_14_Warning) warn_text += "MA7x14 | "; if(MA7_Cross_21_Warning) warn_text += "MA7x21 | "; if(MA50_Break_Warning) warn_text += "🚨 MA50 BREAK | "; if(Fib_Reject_Warning) warn_text += "FIB REJECT | "; if(MA_Reject_Warning) warn_text += "MA REJECT"; ObjectSetString(0, "WarningLabel", OBJPROP_TEXT, warn_text); ObjectSetInteger(0, "WarningLabel", OBJPROP_COLOR, clrRed); ObjectSetInteger(0, "WarningLabel", OBJPROP_FONTSIZE, 10); } else { ObjectDelete(0, "WarningLabel"); } } //+------------------------------------------------------------------+ void MarkRunners() { double current = SymbolInfoDouble(_Symbol, SYMBOL_BID); // Update distances for(int i=0; i OpenPositions[i].distance_from_current) { Position temp = OpenPositions[i]; OpenPositions[i] = OpenPositions[j]; OpenPositions[j] = temp; } } } // Mark top N as runners for(int i=0; i=0; i--) { if(PositionGetTicket(i) == 0) continue; if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue; if(PositionGetInteger(POSITION_MAGIC) != MagicNumber) continue; ulong ticket = PositionGetTicket(i); bool is_buy = PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY; // Find in array int idx = -1; for(int j=0; j= 0 && OpenPositions[idx].is_runner) { Print("🏃 RUNNER PROTECTED: ", OpenPositions[idx].setup_name, " | Distance: ", (int)OpenPositions[idx].distance_from_current); continue; } bool should_close = false; // Close opposing trades if(is_buy && (Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND)) should_close = true; if(!is_buy && (Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND)) should_close = true; if(should_close) { if(Trade.PositionClose(ticket)) { ClosedByReversal++; Print("✂ FULL REVERSAL CLOSE: ", is_buy ? "BUY" : "SELL"); } } } } //+------------------------------------------------------------------+ void UpdateIndicators() { for(int i=0; i<10; i++) { double curr[1], prev[1], prev2[1]; if(CopyBuffer(MA_Handles[i], 0, 0, 1, curr) > 0) MA_Current[i] = curr[0]; if(CopyBuffer(MA_Handles[i], 0, 1, 1, prev) > 0) MA_Previous[i] = prev[0]; if(CopyBuffer(MA_Handles[i], 0, 2, 1, prev2) > 0) MA_Prev2[i] = prev2[0]; } double k_curr[1], k_prev[1], k_prev2[1], d_curr[1]; if(CopyBuffer(Stoch_Handle, MAIN_LINE, 0, 1, k_curr) > 0) Stoch_K_Current = k_curr[0]; if(CopyBuffer(Stoch_Handle, MAIN_LINE, 1, 1, k_prev) > 0) Stoch_K_Previous = k_prev[0]; if(CopyBuffer(Stoch_Handle, MAIN_LINE, 2, 1, k_prev2) > 0) Stoch_K_Prev2 = k_prev2[0]; if(CopyBuffer(Stoch_Handle, SIGNAL_LINE, 0, 1, d_curr) > 0) Stoch_D_Current = d_curr[0]; double atr[1], adx[1]; if(CopyBuffer(ATR_Handle, 0, 0, 1, atr) > 0) Current_ATR = atr[0]; if(CopyBuffer(ADX_Handle, 0, 0, 1, adx) > 0) Current_ADX = adx[0]; } //+------------------------------------------------------------------+ bool IsSetupValidForMode(SETUP_TYPE setup, bool is_buy) { if(!Use_Market_Mode_Filter) return true; // During PULLBACK - allow pullback entries if(Current_State == STATE_PULLBACK) { if(setup == SETUP_CTRL_PULLBACK || setup == SETUP_MEAN_REV || setup == SETUP_FIB_REJECT) return true; return false; // Only pullback setups during pullback } // During RETRACEMENT - wait for reclaim if(Current_State == STATE_RETRACEMENT) { if(setup == SETUP_CTRL_PULLBACK || setup == SETUP_MEAN_REV) return true; return false; } // During REVERSAL FORMING - reduce aggression if(Current_State == STATE_REVERSAL_FORMING) { // Only conservative setups if(setup == SETUP_MA50_BOUNCE || setup == SETUP_MEAN_REV) return true; return false; } // MODE-BASED FILTERING switch(Current_Mode) { case MODE_STRONG_BULL_TREND: if(!is_buy) return false; break; case MODE_STRONG_BEAR_TREND: if(is_buy) return false; break; case MODE_CHOPPY: if(setup != SETUP_MEAN_REV && setup != SETUP_CTRL_PULLBACK && setup != SETUP_FIB_REJECT) return false; break; case MODE_RANGING: if(setup != SETUP_RANGE_ENGINE && setup != SETUP_MEAN_REV && setup != SETUP_FIB_REJECT) return false; break; } return true; } //+------------------------------------------------------------------+ int CountSetupTrades(SETUP_TYPE setup) { int count = 0; for(int i=0; i= Max_Trades_Per_Setup) return; if(PositionsTotal() >= Max_Total_Trades) return; datetime now = TimeCurrent(); if(now - LastEntryTime[setup_type] < 1) return; LastEntryTime[setup_type] = now; double lot = GetLotSize(); if(lot < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)) return; double sl = buy ? price - Initial_SL_Points * _Point : price + Initial_SL_Points * _Point; double tp = buy ? price + TP_Points * _Point : price - TP_Points * _Point; string comment = setup_name + "|" + EnumToString(Current_Mode) + "|" + EnumToString(Current_State); bool result = false; if(buy) result = Trade.Buy(lot, _Symbol, 0, sl, tp, comment); else result = Trade.Sell(lot, _Symbol, 0, sl, tp, comment); if(result) { TodayTrades++; if(buy) BuyTrades++; else SellTrades++; SetupCount[setup_type]++; 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].partial_tp_hit = false; OpenPositions[size].be_set = false; OpenPositions[size].trailing_active = false; OpenPositions[size].is_runner = false; OpenPositions[size].setup_type = setup_type; OpenPositions[size].setup_name = setup_name; OpenPositions[size].entry_mode = Current_Mode; OpenPositions[size].distance_from_current = 0; Print("✓ ", setup_name, " ", buy ? "BUY" : "SELL", " | State: ", EnumToString(Current_State)); } } //+------------------------------------------------------------------+ 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; int idx = -1; for(int j=0; j= Partial_TP_Points) { double current_lot = PositionGetDouble(POSITION_VOLUME); double close_size = NormalizeDouble(OpenPositions[idx].original_lot * Partial_TP_Percent / 100.0, 2); if(close_size > 0 && close_size <= current_lot) { if(Trade.PositionClosePartial(ticket, close_size)) { OpenPositions[idx].partial_tp_hit = true; } } } // Break Even if(!OpenPositions[idx].be_set && profit_points >= BreakEven_Points) { if((is_buy && current_sl < entry) || (!is_buy && current_sl > entry)) { if(Trade.PositionModify(ticket, entry, current_tp)) { OpenPositions[idx].be_set = true; } } } // Trailing if(profit_points >= BreakEven_Points + 100) { OpenPositions[idx].trailing_active = true; double newSL = 0; bool should_modify = false; if(is_buy) { newSL = current - Trailing_Distance_Points * _Point; if(newSL > current_sl + 30 * _Point) should_modify = true; } else { newSL = current + Trailing_Distance_Points * _Point; if(newSL < current_sl - 30 * _Point) should_modify = true; } if(should_modify) Trade.PositionModify(ticket, newSL, current_tp); } } } //+------------------------------------------------------------------+ void OnTick() { UpdateIndicators(); DetectWarnings(); UpdateMarketMode(); ManagePositions(); static int tick_count = 0; tick_count++; if(tick_count >= 100) { CalculateLevels(); tick_count = 0; } double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double current = (bid + ask) / 2; double previous = iClose(_Symbol, PERIOD_CURRENT, 1); double buffer = MA_Touch_Buffer * _Point; //================================================================= // SETUPS - filtered by state and mode //================================================================= // During pullbacks, focus on counter-pullback entries if(Current_State == STATE_PULLBACK || Current_State == STATE_RETRACEMENT) { // CTRL PULLBACK entries when stoch extreme hit if(Stoch_Extreme_Warning) { bool near_ma = MathAbs(current - MA_Current[3]) / Current_ATR < 1.5; if(near_ma) { if(Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND) OpenTrade(true, ask, "PULLBACK-BUY", SETUP_CTRL_PULLBACK); if(Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) OpenTrade(false, bid, "PULLBACK-SELL", SETUP_CTRL_PULLBACK); } } // MEAN REV at extremes if(Stoch_K_Current <= Stoch_Extreme_Low) OpenTrade(true, ask, "EXTREME-REV-BUY", SETUP_MEAN_REV); if(Stoch_K_Current >= Stoch_Extreme_High) OpenTrade(false, bid, "EXTREME-REV-SELL", SETUP_MEAN_REV); // FIB REJECT during pullback if(Fib_Reject_Warning) { if(Stoch_K_Current >= Stoch_Extreme_High) OpenTrade(false, bid, "FIB-REJECT↓", SETUP_FIB_REJECT); if(Stoch_K_Current <= Stoch_Extreme_Low) OpenTrade(true, ask, "FIB-REJECT↑", SETUP_FIB_REJECT); } } // Normal trend continuation setups if(Current_State == STATE_TREND_CONTINUATION) { // MA14 CROSS if(Current_Mode != MODE_CHOPPY && Current_Mode != MODE_RANGING) { int ma14_crosses = 0; for(int i=0; i<10; i++) if(i != 1 && MA_Current[1] > MA_Current[i]) ma14_crosses++; if(ma14_crosses >= 2) OpenTrade(true, ask, "MA14-CROSS↑", SETUP_MA14_CROSS); ma14_crosses = 0; for(int i=0; i<10; i++) if(i != 1 && MA_Current[1] < MA_Current[i]) ma14_crosses++; if(ma14_crosses >= 2) OpenTrade(false, bid, "MA14-CROSS↓", SETUP_MA14_CROSS); } // MA BOUNCES if(MathAbs(current - MA_Current[3]) <= buffer) { OpenTrade(true, ask, "MA50-BOUNCE↑", SETUP_MA50_BOUNCE); OpenTrade(false, bid, "MA50-BOUNCE↓", SETUP_MA50_BOUNCE); } if(MathAbs(current - MA_Current[4]) <= buffer) { OpenTrade(true, ask, "MA140-BOUNCE↑", SETUP_MA140_BOUNCE); OpenTrade(false, bid, "MA140-BOUNCE↓", SETUP_MA140_BOUNCE); } // FIB BREAKS for(int i=1; i<6; i++) { if(MathAbs(current - PriceLevels[i]) <= buffer) { if(previous < PriceLevels[i]) OpenTrade(true, ask, "FIB-BREAK↑", SETUP_FIB_BREAK); if(previous > PriceLevels[i]) OpenTrade(false, bid, "FIB-BREAK↓", SETUP_FIB_BREAK); } } // MAGNET WALK bool hugging = (MathAbs(current - MA_Current[2]) / Current_ATR < 0.7); if(hugging && MA_Current[0] > MA_Current[3]) OpenTrade(true, ask, "MAGNET-WALK↑", SETUP_MAGNET_WALK); if(hugging && MA_Current[0] < MA_Current[3]) OpenTrade(false, bid, "MAGNET-WALK↓", SETUP_MAGNET_WALK); } // Range setups if(Current_Mode == MODE_RANGING) { if(MathAbs(current - PriceLevels[1]) < buffer && Stoch_K_Current < 35) OpenTrade(true, ask, "RANGE-BUY", SETUP_RANGE_ENGINE); if(MathAbs(current - PriceLevels[5]) < buffer && Stoch_K_Current > 65) OpenTrade(false, bid, "RANGE-SELL", SETUP_RANGE_ENGINE); } } //+------------------------------------------------------------------+