//+------------------------------------------------------------------+ //| QuarterTheory_VIZION_FINAL_v5.0.mq5 | //| 150PT SL | 300PT TRAIL | 4000PT TP | RUNNERS PROTECTED | //| Tight Entry Risk | Aggressive Trailing | Max Profit Runners | //+------------------------------------------------------------------+ #property copyright "QuarterTheory x VIZION - Final v5.0 Tight SL" #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 "=== TIGHT SL + AGGRESSIVE TRAIL SYSTEM ===" input int Initial_SL_Points = 150; // Tight entry SL input int BreakEven_Points = 300; // Move to BE at 300 input int Trailing_Distance_Points = 300; // Trail by 300 input int TP_Points = 4000; // Final TP at 4000 input int Partial_TP_Points = 900; // First partial at 900 input double Partial_TP_Percent = 33.0; // Close 33% at partial //================ 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_CONTINUATION, // Clean trend - only trend-aligned trades STATE_PULLBACK, // Shallow pullback (7 dip, 14/21 hold) - wait for re-entry STATE_RETRACEMENT, // Deeper retracement (7 crosses 14/21) - wait for re-entry STATE_FULL_REVERSAL, // Confirmed reversal (50 broken) - flip trades STATE_CHOPPY, // Choppy - mean reversion only STATE_RANGING // Ranging - range engine only }; 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_CONTINUATION; 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 - TIGHT SL"); Print("ENTRY SL: 150pts | TRAIL: 300pts | TP: 4000pts"); Print("PULLBACK DETECTION | RUNNERS PROTECTED"); 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); double buffer = MA_Touch_Buffer * _Point; // Check stoch rejections at key levels bool stoch_reject_at_20 = (Stoch_K_Previous > 20 && Stoch_K_Current <= 20) || (Stoch_K_Previous < 20 && Stoch_K_Current >= 20); bool stoch_reject_at_35 = (Stoch_K_Previous > 35 && Stoch_K_Current <= 35) || (Stoch_K_Previous < 35 && Stoch_K_Current >= 35); bool stoch_reject_at_50 = (Stoch_K_Previous > 50 && Stoch_K_Current <= 50) || (Stoch_K_Previous < 50 && Stoch_K_Current >= 50); bool stoch_reject_at_65 = (Stoch_K_Previous > 65 && Stoch_K_Current <= 65) || (Stoch_K_Previous < 65 && Stoch_K_Current >= 65); bool stoch_reject_at_80 = (Stoch_K_Previous > 80 && Stoch_K_Current <= 80) || (Stoch_K_Previous < 80 && Stoch_K_Current >= 80); bool stoch_rejection = stoch_reject_at_20 || stoch_reject_at_35 || stoch_reject_at_50 || stoch_reject_at_65 || stoch_reject_at_80; // Check fib rejection (price at fib + stoch rejection) bool at_fib = false; for(int i=1; i<6; i++) { if(MathAbs(current - PriceLevels[i]) <= buffer) { at_fib = true; break; } } bool fib_plus_stoch_reject = at_fib && stoch_rejection; // 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]; 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]; // RANGING MODE CHECK (separate from trending states) if(Current_Mode == MODE_RANGING) { return STATE_RANGING; } // CHOPPY MODE CHECK if(Current_Mode == MODE_CHOPPY) { return STATE_CHOPPY; } // BULLISH TREND STATES if(Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND) { // FULL REVERSAL: 50 broken to downside if(!ma7_above_50 && !ma14_above_50) { return STATE_FULL_REVERSAL; } // RETRACEMENT: 7 crosses 14 or 21 (deeper pullback) // + Fib/Stoch rejection signals if((!ma7_above_14 || !ma7_above_21) && (MA7_Cross_14_Warning || MA7_Cross_21_Warning)) { if(fib_plus_stoch_reject || Fib_Reject_Warning || MA_Reject_Warning) { return STATE_RETRACEMENT; } } // PULLBACK: 7 dips but 14/21 still above 50 (shallow pullback) // Stoch extreme or fib/MA rejection if(ma14_above_50 && ma21_above_50 && (Stoch_Extreme_Warning || fib_plus_stoch_reject)) { return STATE_PULLBACK; } // CONTINUATION: Clean bullish structure if(ma7_above_21 && ma21_above_50) { return STATE_CONTINUATION; } } // BEARISH TREND STATES if(Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) { // FULL REVERSAL: 50 broken to upside if(!ma7_below_50 && !ma14_below_50) { return STATE_FULL_REVERSAL; } // RETRACEMENT: 7 crosses 14 or 21 (deeper pullback) // + Fib/Stoch rejection signals if((!ma7_below_14 || !ma7_below_21) && (MA7_Cross_14_Warning || MA7_Cross_21_Warning)) { if(fib_plus_stoch_reject || Fib_Reject_Warning || MA_Reject_Warning) { return STATE_RETRACEMENT; } } // PULLBACK: 7 rises but 14/21 still below 50 (shallow pullback) // Stoch extreme or fib/MA rejection if(ma14_below_50 && ma21_below_50 && (Stoch_Extreme_Warning || fib_plus_stoch_reject)) { return STATE_PULLBACK; } // CONTINUATION: Clean bearish structure if(ma7_below_21 && ma21_below_50) { return STATE_CONTINUATION; } } // Default to continuation if unclear return STATE_CONTINUATION; } //+------------------------------------------------------------------+ 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_CONTINUATION: state_text += "CONTINUATION → (TREND ONLY)"; state_color = clrLime; break; case STATE_PULLBACK: state_text += "PULLBACK ↩ (WAIT RE-ENTRY)"; state_color = clrYellow; break; case STATE_RETRACEMENT: state_text += "RETRACEMENT ↪ (WAIT RE-ENTRY)"; state_color = clrOrange; break; case STATE_FULL_REVERSAL: state_text += "FULL REVERSAL 🔄 (FLIPPING)"; state_color = clrRed; break; case STATE_CHOPPY: state_text += "CHOPPY ⚡ (MEAN REV ONLY)"; state_color = clrViolet; break; case STATE_RANGING: state_text += "RANGING ↔ (RANGE ENGINE)"; state_color = clrAqua; 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; // STATE-BASED FILTERING (Primary Logic) // CONTINUATION: Only trend-aligned trades allowed if(Current_State == STATE_CONTINUATION) { // In bull trend continuation - NO SHORTS if((Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND) && !is_buy) return false; // In bear trend continuation - NO LONGS if((Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) && is_buy) return false; // All setups allowed in trend direction return true; } // PULLBACK: Wait for re-entry - only counter-pullback setups if(Current_State == STATE_PULLBACK) { // Only re-entry setups allowed if(setup == SETUP_CTRL_PULLBACK || setup == SETUP_MEAN_REV || setup == SETUP_FIB_REJECT || setup == SETUP_MA50_BOUNCE || setup == SETUP_MA140_BOUNCE) { // Must be in trend direction if((Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND) && is_buy) return true; if((Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) && !is_buy) return true; } return false; } // RETRACEMENT: Wait for stronger re-entry signal if(Current_State == STATE_RETRACEMENT) { // Only specific re-entry setups after deeper retracement if(setup == SETUP_CTRL_PULLBACK || setup == SETUP_MEAN_REV || setup == SETUP_MA50_BOUNCE || setup == SETUP_MA140_BOUNCE) { // Must be in trend direction if((Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND) && is_buy) return true; if((Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) && !is_buy) return true; } return false; } // CHOPPY: Mean reversion only if(Current_State == STATE_CHOPPY) { if(setup == SETUP_MEAN_REV || setup == SETUP_CTRL_PULLBACK || setup == SETUP_FIB_REJECT) return true; return false; } // RANGING: Range engine and bounces only if(Current_State == STATE_RANGING) { if(setup == SETUP_RANGE_ENGINE || setup == SETUP_MEAN_REV || setup == SETUP_FIB_REJECT || setup == SETUP_MA50_BOUNCE || setup == SETUP_MA140_BOUNCE) return true; return false; } // FULL REVERSAL: Allow flipped trades (handled by mode change) if(Current_State == STATE_FULL_REVERSAL) { // Mode should flip, then continuation logic applies return true; } 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; //================================================================= // STATE-BASED SETUP EXECUTION //================================================================= // CONTINUATION STATE: All trend-aligned setups active if(Current_State == STATE_CONTINUATION) { // MA14 CROSS 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); } if(MathAbs(current - MA_Current[5]) <= buffer) { OpenTrade(true, ask, "MA230-BOUNCE↑", SETUP_MA230_BOUNCE); OpenTrade(false, bid, "MA230-BOUNCE↓", SETUP_MA230_BOUNCE); } if(MathAbs(current - MA_Current[6]) <= buffer) { OpenTrade(true, ask, "MA500-TOUCH↑", SETUP_MA500_TOUCH); OpenTrade(false, bid, "MA500-TOUCH↓", SETUP_MA500_TOUCH); } // 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); // STAIRCASE if(MA_Current[1] > MA_Previous[1] && MA_Current[1] > MA_Current[3]) OpenTrade(true, ask, "STAIRCASE↑", SETUP_STAIRCASE_ADV); if(MA_Current[1] < MA_Previous[1] && MA_Current[1] < MA_Current[3]) OpenTrade(false, bid, "STAIRCASE↓", SETUP_STAIRCASE_ADV); // MFIB LADDER if(MathAbs(current - MFIB_Level_618) <= buffer) { if(previous <= MFIB_Level_618) OpenTrade(true, ask, "MFIB-LADDER↑", SETUP_MFIB_LADDER); if(previous >= MFIB_Level_618) OpenTrade(false, bid, "MFIB-LADDER↓", SETUP_MFIB_LADDER); } // MFIB PRESS bool near_mfib = MathAbs(current - MFIB_Level_050) / Current_ATR < 1.2; if(near_mfib) { if(MA_Current[1] > MA_Current[3]) OpenTrade(true, ask, "MFIB-PRESS↑", SETUP_MFIB_PRESS); if(MA_Current[1] < MA_Current[3]) OpenTrade(false, bid, "MFIB-PRESS↓", SETUP_MFIB_PRESS); } // TF RESET if(Stoch_K_Current < 35 && MA_Current[0] > MA_Current[6]) OpenTrade(true, ask, "TF-RESET↑", SETUP_TF_RESET); if(Stoch_K_Current > 65 && MA_Current[0] < MA_Current[6]) OpenTrade(false, bid, "TF-RESET↓", SETUP_TF_RESET); } // PULLBACK/RETRACEMENT STATE: Wait for re-entry signals if(Current_State == STATE_PULLBACK || Current_State == STATE_RETRACEMENT) { // CTRL PULLBACK when stoch extreme hit + fib/MA reject if(Stoch_Extreme_Warning || Fib_Reject_Warning || MA_Reject_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, "RE-ENTRY-BUY↑", SETUP_CTRL_PULLBACK); if(Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) OpenTrade(false, bid, "RE-ENTRY-SELL↓", SETUP_CTRL_PULLBACK); } } // MEAN REV at stoch extremes (15/85) if(Stoch_K_Current <= Stoch_Extreme_Low) { if(Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND) OpenTrade(true, ask, "EXTREME-BUY↑", SETUP_MEAN_REV); } if(Stoch_K_Current >= Stoch_Extreme_High) { if(Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) OpenTrade(false, bid, "EXTREME-SELL↓", SETUP_MEAN_REV); } // FIB REJECT re-entry if(Fib_Reject_Warning) { if(Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND) OpenTrade(true, ask, "FIB-RE-ENTRY↑", SETUP_FIB_REJECT); if(Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) OpenTrade(false, bid, "FIB-RE-ENTRY↓", SETUP_FIB_REJECT); } // MA BOUNCES during pullback (re-entry) if(MathAbs(current - MA_Current[3]) <= buffer) { if(Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND) OpenTrade(true, ask, "MA50-RE-ENTRY↑", SETUP_MA50_BOUNCE); if(Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) OpenTrade(false, bid, "MA50-RE-ENTRY↓", SETUP_MA50_BOUNCE); } if(MathAbs(current - MA_Current[4]) <= buffer) { if(Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND) OpenTrade(true, ask, "MA140-RE-ENTRY↑", SETUP_MA140_BOUNCE); if(Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) OpenTrade(false, bid, "MA140-RE-ENTRY↓", SETUP_MA140_BOUNCE); } } // CHOPPY STATE: Mean reversion only if(Current_State == STATE_CHOPPY) { bool near_ma = MathAbs(current - MA_Current[3]) / Current_ATR < 1.5; if(near_ma && Stoch_K_Current < Stoch_Low) OpenTrade(true, ask, "CHOP-MEAN-REV-BUY", SETUP_MEAN_REV); if(near_ma && Stoch_K_Current > Stoch_High) OpenTrade(false, bid, "CHOP-MEAN-REV-SELL", SETUP_MEAN_REV); // FIB rejects in chop for(int i=1; i<6; i++) { if(MathAbs(current - PriceLevels[i]) <= buffer) { if(Stoch_K_Current > Stoch_High) OpenTrade(false, bid, "CHOP-FIB-REJECT↓", SETUP_FIB_REJECT); if(Stoch_K_Current < Stoch_Low) OpenTrade(true, ask, "CHOP-FIB-REJECT↑", SETUP_FIB_REJECT); } } } // RANGING STATE: Range engine if(Current_State == STATE_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); // MA bounces in range if(MathAbs(current - MA_Current[3]) <= buffer) { if(Stoch_K_Current < 35) OpenTrade(true, ask, "RANGE-MA50-BUY", SETUP_MA50_BOUNCE); if(Stoch_K_Current > 65) OpenTrade(false, bid, "RANGE-MA50-SELL", SETUP_MA50_BOUNCE); } } } //+------------------------------------------------------------------+