//+------------------------------------------------------------------+ //| QuarterTheory_VIZION_FINAL_v5.2.mq5 | //| Directional Re-Entry Filters + MFIB/Stoch Reject Pullbacks | //| PLUS: 3+ Warning Confluence => Pullback trigger (aligned) | //| 150PT SL | 300PT TRAIL | 4000PT TP | RUNNERS PROTECTED | //+------------------------------------------------------------------+ #property copyright "QuarterTheory x VIZION" #property version "5.20" #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; // reserved for future expansion 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 MODE_FAMILY { FAMILY_TRENDING = 0, FAMILY_RANGING = 1, FAMILY_CHOP = 2, FAMILY_TRANSITIONAL = 3 }; enum TREND_BIAS { BIAS_NEUTRAL = 0, BIAS_BULL = 1, BIAS_BEAR = -1 }; enum TREND_STRENGTH { STRENGTH_WEAK = 0, STRENGTH_CONFIRMED = 1, STRENGTH_STRONG = 2 }; enum PRICE_STATE { STATE_CONTINUATION = 0, // Trend expansion / clean STATE_PULLBACK = 1, // Counter-move but structure intact STATE_DEEP_RETRACEMENT = 2, // Threatening structure / testing MA50+ STATE_REVERSAL_ATTEMPT = 3, // Structure break + failed reclaim attempt STATE_REVERSAL_CONFIRMED = 4, // New bias confirmed // Range states STATE_RANGE_MID_DRIFT = 10, STATE_RANGE_EDGE_TEST = 11, STATE_RANGE_REJECTION = 12, STATE_RANGE_BREAK_ATTEMPT = 13, STATE_RANGE_BREAK_CONFIRMED = 14, // Chop states STATE_CHOP_NOISE = 20, STATE_CHOP_VOL_SPIKE = 21, STATE_CHOP_SQUEEZE = 22, STATE_CHOP_FAKEOUT_LOOP = 23, STATE_UNKNOWN = 99 }; 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; MODE_FAMILY Current_Family = FAMILY_TRANSITIONAL; TREND_BIAS Current_Bias = BIAS_NEUTRAL; TREND_STRENGTH Current_Strength = STRENGTH_WEAK; PRICE_STATE Current_State = STATE_UNKNOWN; MODE_FAMILY Prev_Family = FAMILY_TRANSITIONAL; TREND_BIAS Prev_Bias = BIAS_NEUTRAL; TREND_STRENGTH Prev_Strength = STRENGTH_WEAK; 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; // Classic fib reject bool MFIB_Reject_Warning = false; // MFIB reject bool MA_Reject_Warning = false; bool Stoch_Extreme_Warning = false; bool Stoch_Reject_Warning = false; bool Pullback_Warning = false; bool Retracement_Warning = false; // NEW: warning confluence int Warning_Confluence_Count = 0; bool Warning_Confluence_3Plus = false; struct PositionRec { 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; MODE_FAMILY entry_family; TREND_BIAS entry_bias; TREND_STRENGTH entry_strength; double distance_from_current; }; PositionRec OpenPositions[]; int TodayTrades = 0; int BuyTrades = 0; int SellTrades = 0; int ClosedByReversal = 0; int SetupCount[17]; datetime LastEntryTime[17]; //================ HELPERS ==================// double MidPrice() { double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); return (bid + ask) / 2.0; } bool NearLevel(const double price, const double level, const double tolPoints) { return (MathAbs(price - level) <= tolPoints * _Point); } bool StochCrossUp() { // K crosses above D (approx) on current bar return (Stoch_K_Previous < Stoch_D_Current && Stoch_K_Current >= Stoch_D_Current); } bool StochCrossDown() { return (Stoch_K_Previous > Stoch_D_Current && Stoch_K_Current <= Stoch_D_Current); } bool IsBullBias() { return (Current_Bias == BIAS_BULL); } bool IsBearBias() { return (Current_Bias == BIAS_BEAR); } // Reclaim / reject MA50 logic bool Bull_MA50_Reclaimed() { bool reclaimed = (MA_Previous[0] <= MA_Previous[3]) && (MA_Current[0] > MA_Current[3]); double low0 = iLow(_Symbol, PERIOD_CURRENT, 0); double close0 = iClose(_Symbol, PERIOD_CURRENT, 0); bool rejected = (low0 <= MA_Current[3] && close0 > MA_Current[3] && (StochCrossUp() || Stoch_K_Current > 50)); return (reclaimed || rejected); } bool Bear_MA50_Reclaimed() { bool reclaimed = (MA_Previous[0] >= MA_Previous[3]) && (MA_Current[0] < MA_Current[3]); double high0 = iHigh(_Symbol, PERIOD_CURRENT, 0); double close0 = iClose(_Symbol, PERIOD_CURRENT, 0); bool rejected = (high0 >= MA_Current[3] && close0 < MA_Current[3] && (StochCrossDown() || Stoch_K_Current < 50)); return (reclaimed || rejected); } //+------------------------------------------------------------------+ int OnInit() { Print("========================================"); Print("QuarterTheory_VIZION_FINAL v5.2"); Print("Added: 3+ Warning Confluence -> Pullback trigger (aligned)"); 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(); 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 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]; } //+------------------------------------------------------------------+ void DetectWarnings() { double current = MidPrice(); double bufferPts = (double)MA_Touch_Buffer; // Reset warnings MA7_Cross_14_Warning = false; MA7_Cross_21_Warning = false; MA50_Break_Warning = false; Fib_Reject_Warning = false; MFIB_Reject_Warning = false; MA_Reject_Warning = false; Stoch_Extreme_Warning = false; Stoch_Reject_Warning = false; Pullback_Warning = false; Retracement_Warning = false; // 1) STOCH extremes if(Stoch_K_Current <= Stoch_Extreme_Low || Stoch_K_Current >= Stoch_Extreme_High) Stoch_Extreme_Warning = true; // 2) STOCH reject at ANY meaningful band bool stoch_reject_down = (StochCrossDown() && Stoch_K_Current > 50); bool stoch_reject_up = (StochCrossUp() && Stoch_K_Current < 50); if(stoch_reject_down || stoch_reject_up) Stoch_Reject_Warning = true; // 3) MA7 x MA14 cross 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; } // 4) MA7 x MA21 cross 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; } // 5) MA50 break 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; // 6) Classic fib reject if at fib + stoch extreme OR stoch reject bool at_fib = false; for(int i=1; i<6; i++) { if(NearLevel(current, PriceLevels[i], bufferPts)) { at_fib = true; break; } } if(at_fib && (Stoch_Extreme_Warning || Stoch_Reject_Warning)) { Fib_Reject_Warning = true; Pullback_Warning = true; } // 7) MFIB reject bool at_mfib = NearLevel(current, MFIB_Level_236, bufferPts) || NearLevel(current, MFIB_Level_382, bufferPts) || NearLevel(current, MFIB_Level_050, bufferPts) || NearLevel(current, MFIB_Level_618, bufferPts) || NearLevel(current, MFIB_Level_786, bufferPts); if(at_mfib && (Stoch_Extreme_Warning || Stoch_Reject_Warning)) { MFIB_Reject_Warning = true; Pullback_Warning = true; } // 8) MA reject with stoch signal bool at_ma50 = NearLevel(current, MA_Current[3], bufferPts); bool at_ma140 = NearLevel(current, MA_Current[4], bufferPts); bool at_ma230 = NearLevel(current, MA_Current[5], bufferPts); if((at_ma50 || at_ma140 || at_ma230) && (Stoch_Extreme_Warning || Stoch_Reject_Warning)) { MA_Reject_Warning = true; Pullback_Warning = true; } // 9) NEW: WARNING CONFLUENCE (3+) Warning_Confluence_Count = 0; if(Stoch_Extreme_Warning) Warning_Confluence_Count++; if(Stoch_Reject_Warning) Warning_Confluence_Count++; if(MA7_Cross_14_Warning) Warning_Confluence_Count++; if(MA7_Cross_21_Warning) Warning_Confluence_Count++; if(MA50_Break_Warning) Warning_Confluence_Count++; if(Fib_Reject_Warning) Warning_Confluence_Count++; if(MFIB_Reject_Warning) Warning_Confluence_Count++; if(MA_Reject_Warning) Warning_Confluence_Count++; Warning_Confluence_3Plus = (Warning_Confluence_Count >= 3); } //+------------------------------------------------------------------+ // Family/Bias/Strength detection void DetectFamilyBiasStrength(MODE_FAMILY &family, TREND_BIAS &bias, TREND_STRENGTH &strength) { double current = MidPrice(); 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]); // quick chop/range tests 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 = false; if(Current_ATR > 0.0) ma_clustered = ((MathAbs(MA_Current[0] - MA_Current[3]) / Current_ATR) < Chop_ATR_Threshold); bool is_choppy = (ma_clustered || Current_ADX < 15); // bias if(mas_aligned_bull) bias = BIAS_BULL; else if(mas_aligned_bear) bias = BIAS_BEAR; else { if(MA_Current[0] > MA_Current[3]) bias = BIAS_BULL; else if(MA_Current[0] < MA_Current[3]) bias = BIAS_BEAR; else bias = BIAS_NEUTRAL; } // family if(is_choppy && !(mas_aligned_bull || mas_aligned_bear)) family = FAMILY_CHOP; else if(is_ranging && !(mas_aligned_bull || mas_aligned_bear)) family = FAMILY_RANGING; else if(bias != BIAS_NEUTRAL) family = FAMILY_TRENDING; else family = FAMILY_TRANSITIONAL; // strength if(Current_ADX > 25 && (mas_aligned_bull || mas_aligned_bear)) strength = STRENGTH_STRONG; else if(Current_ADX > 18 && (mas_aligned_bull || mas_aligned_bear)) strength = STRENGTH_CONFIRMED; else strength = STRENGTH_WEAK; } //+------------------------------------------------------------------+ PRICE_STATE DetermineStateFromContext() { //================ RANGE =================// if(Current_Family == FAMILY_RANGING) { double current = MidPrice(); double bufferPts = (double)MA_Touch_Buffer; bool near_low = NearLevel(current, PriceLevels[1], bufferPts) || NearLevel(current, PriceLevels[0], bufferPts); bool near_high = NearLevel(current, PriceLevels[5], bufferPts) || NearLevel(current, PriceLevels[6], bufferPts); if(near_low || near_high) return STATE_RANGE_EDGE_TEST; if(Stoch_Reject_Warning || Stoch_Extreme_Warning || Fib_Reject_Warning || MFIB_Reject_Warning) return STATE_RANGE_REJECTION; double close0 = iClose(_Symbol, PERIOD_CURRENT, 0); if(close0 > PriceLevels[6] || close0 < PriceLevels[0]) return STATE_RANGE_BREAK_CONFIRMED; if(NearLevel(current, PriceLevels[6], bufferPts) || NearLevel(current, PriceLevels[0], bufferPts)) return STATE_RANGE_BREAK_ATTEMPT; return STATE_RANGE_MID_DRIFT; } //================ CHOP =================// if(Current_Family == FAMILY_CHOP) { if(Current_ADX < 12 && !Stoch_Reject_Warning) return STATE_CHOP_NOISE; if(Current_ATR > 0) { double body = MathAbs(iClose(_Symbol, PERIOD_CURRENT, 0) - iOpen(_Symbol, PERIOD_CURRENT, 0)); if((body / Current_ATR) > 1.2) return STATE_CHOP_VOL_SPIKE; double cluster = MathAbs(MA_Current[0] - MA_Current[3]) / Current_ATR; if(Current_ADX < 15 && cluster < 0.25) return STATE_CHOP_SQUEEZE; } if(Stoch_Reject_Warning) return STATE_CHOP_FAKEOUT_LOOP; return STATE_CHOP_NOISE; } //================ TRENDING / TRANSITIONAL =================// 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]); bool retraceSignal = (MA7_Cross_14_Warning || MA7_Cross_21_Warning); // NEW: 3+ warning confluence only counts if backbone intact for that bias bool structure_intact_bull = (ma14_above_50 && ma21_above_50); bool structure_intact_bear = (ma14_below_50 && ma21_below_50); bool confluenceAligned = false; if(IsBullBias() && structure_intact_bull) confluenceAligned = Warning_Confluence_3Plus; if(IsBearBias() && structure_intact_bear) confluenceAligned = Warning_Confluence_3Plus; bool pullbackSignal = (Pullback_Warning || MFIB_Reject_Warning || Fib_Reject_Warning || Stoch_Reject_Warning || confluenceAligned); if(IsBullBias()) { // Reversal confirmed: backbone flipped below 50 if(ma7_below_50 && !ma14_above_50 && !ma21_above_50) return STATE_REVERSAL_CONFIRMED; // Reversal attempt: MA50 pressure + other signals if(MA50_Break_Warning && (retraceSignal || Stoch_Extreme_Warning || Stoch_Reject_Warning || Warning_Confluence_3Plus)) return STATE_REVERSAL_ATTEMPT; // Deep retracement: MA7 not above key MAs OR testing MA50 + signals if((!ma7_above_14 || !ma7_above_21 || !ma7_above_50) && (pullbackSignal || retraceSignal)) return STATE_DEEP_RETRACEMENT; // Pullback: backbone intact + any pullback trigger (including aligned 3+) if(structure_intact_bull && pullbackSignal) return STATE_PULLBACK; return STATE_CONTINUATION; } if(IsBearBias()) { if(ma7_above_50 && !ma14_below_50 && !ma21_below_50) return STATE_REVERSAL_CONFIRMED; if(MA50_Break_Warning && (retraceSignal || Stoch_Extreme_Warning || Stoch_Reject_Warning || Warning_Confluence_3Plus)) return STATE_REVERSAL_ATTEMPT; if((!ma7_below_14 || !ma7_below_21 || !ma7_below_50) && (pullbackSignal || retraceSignal)) return STATE_DEEP_RETRACEMENT; if(structure_intact_bear && pullbackSignal) return STATE_PULLBACK; return STATE_CONTINUATION; } return STATE_UNKNOWN; } //+------------------------------------------------------------------+ string FamilyToText(MODE_FAMILY f) { switch(f) { case FAMILY_TRENDING: return "Trending"; case FAMILY_RANGING: return "Ranging"; case FAMILY_CHOP: return "Chop"; case FAMILY_TRANSITIONAL: return "Transitional"; } return "Unknown"; } string BiasToText(TREND_BIAS b) { if(b == BIAS_BULL) return "Bull"; if(b == BIAS_BEAR) return "Bear"; return "Neutral"; } string StrengthToText(TREND_STRENGTH s) { switch(s) { case STRENGTH_WEAK: return "Weak"; case STRENGTH_CONFIRMED: return "Confirmed"; case STRENGTH_STRONG: return "Strong"; } return "Weak"; } string StateToText(PRICE_STATE s) { switch(s) { case STATE_CONTINUATION: return "Continuation"; case STATE_PULLBACK: return "Pullback"; case STATE_DEEP_RETRACEMENT: return "Deep Retracement"; case STATE_REVERSAL_ATTEMPT: return "Reversal Attempt"; case STATE_REVERSAL_CONFIRMED: return "Reversal Confirmed"; case STATE_RANGE_MID_DRIFT: return "Range: Mid Drift"; case STATE_RANGE_EDGE_TEST: return "Range: Edge Test"; case STATE_RANGE_REJECTION: return "Range: Rejection"; case STATE_RANGE_BREAK_ATTEMPT: return "Range: Break Attempt"; case STATE_RANGE_BREAK_CONFIRMED: return "Range: Break Confirmed"; case STATE_CHOP_NOISE: return "Chop: Noise"; case STATE_CHOP_VOL_SPIKE: return "Chop: Vol Spike"; case STATE_CHOP_SQUEEZE: return "Chop: Squeeze"; case STATE_CHOP_FAKEOUT_LOOP: return "Chop: Fakeout Loop"; default: return "Unknown"; } } //+------------------------------------------------------------------+ 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, 20); string mode_text = "MODE: " + FamilyToText(Current_Family); if(Current_Family == FAMILY_TRENDING) mode_text += " | " + StrengthToText(Current_Strength) + " " + BiasToText(Current_Bias); color mode_color = clrYellow; if(Current_Family == FAMILY_TRENDING) { if(Current_Bias == BIAS_BULL) mode_color = (Current_Strength == STRENGTH_STRONG ? clrLime : (Current_Strength == STRENGTH_CONFIRMED ? clrGreenYellow : clrGreen)); if(Current_Bias == BIAS_BEAR) mode_color = (Current_Strength == STRENGTH_STRONG ? clrRed : (Current_Strength == STRENGTH_CONFIRMED ? clrOrangeRed : clrOrange)); } else if(Current_Family == FAMILY_RANGING) mode_color = clrAqua; else if(Current_Family == FAMILY_CHOP) mode_color = clrViolet; 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, 40); string state_text = "STATE: " + StateToText(Current_State); if(Current_Family == FAMILY_TRENDING && (Current_State == STATE_PULLBACK || Current_State == STATE_DEEP_RETRACEMENT)) { if(IsBullBias() && !Bull_MA50_Reclaimed()) state_text += " | ACTION: SELLS-ONLY (until MA50 reclaim/reject-up)"; else if(IsBearBias() && !Bear_MA50_Reclaimed()) state_text += " | ACTION: BUYS-ONLY (until MA50 reclaim/reject-down)"; else state_text += " | ACTION: TREND-OK"; } color state_color = clrWhite; if(Current_State == STATE_CONTINUATION) state_color = clrLime; else if(Current_State == STATE_PULLBACK) state_color = clrYellow; else if(Current_State == STATE_DEEP_RETRACEMENT) state_color = clrOrange; else if(Current_State == STATE_REVERSAL_ATTEMPT) state_color = clrOrangeRed; else if(Current_State == STATE_REVERSAL_CONFIRMED) state_color = clrRed; else if(Current_Family == FAMILY_RANGING) state_color = clrAqua; else if(Current_Family == FAMILY_CHOP) state_color = clrViolet; ObjectSetString(0, "StateLabel", OBJPROP_TEXT, state_text); ObjectSetInteger(0, "StateLabel", OBJPROP_COLOR, state_color); ObjectSetInteger(0, "StateLabel", OBJPROP_FONTSIZE, 11); // WARNING LABEL bool anyWarn = (Stoch_Extreme_Warning || Stoch_Reject_Warning || MA7_Cross_14_Warning || MA7_Cross_21_Warning || MA50_Break_Warning || Fib_Reject_Warning || MFIB_Reject_Warning || MA_Reject_Warning || Warning_Confluence_3Plus); if(anyWarn) { 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, 60); string warn_text = "WARN: "; if(Stoch_Extreme_Warning) warn_text += "STOCH-EXT | "; if(Stoch_Reject_Warning) warn_text += "STOCH-REJECT | "; 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(MFIB_Reject_Warning) warn_text += "MFIB-REJECT | "; if(MA_Reject_Warning) warn_text += "MA-REJECT | "; if(Warning_Confluence_3Plus) warn_text += "3+CONFLUENCE | "; warn_text += "W=" + IntegerToString(Warning_Confluence_Count); ObjectSetString(0, "WarningLabel", OBJPROP_TEXT, warn_text); ObjectSetInteger(0, "WarningLabel", OBJPROP_COLOR, clrRed); ObjectSetInteger(0, "WarningLabel", OBJPROP_FONTSIZE, 10); } else { ObjectDelete(0, "WarningLabel"); } } //+------------------------------------------------------------------+ void UpdateModeAndState() { MODE_FAMILY detected_family; TREND_BIAS detected_bias; TREND_STRENGTH detected_strength; DetectFamilyBiasStrength(detected_family, detected_bias, detected_strength); // apply detected context before state calc Current_Family = detected_family; Current_Bias = detected_bias; Current_Strength = detected_strength; PRICE_STATE detected_state = DetermineStateFromContext(); bool changed = (detected_family != Prev_Family) || (detected_bias != Prev_Bias) || (detected_strength != Prev_Strength); if(changed) { int required = Mode_Confirmation_Bars; if(detected_state == STATE_REVERSAL_CONFIRMED) required = 1; if(detected_family == Prev_Family && detected_bias == Prev_Bias && detected_strength == Prev_Strength) { Mode_Confirmation_Count++; if(Mode_Confirmation_Count >= required) { Prev_Family = detected_family; Prev_Bias = detected_bias; Prev_Strength = detected_strength; Current_Family = detected_family; Current_Bias = detected_bias; Current_Strength = detected_strength; Current_State = detected_state; Mode_Confirmation_Count = 0; Reversal_Confirm_Counter = 0; if(Current_State == STATE_REVERSAL_CONFIRMED) CloseOnFullReversal(); } } else { Prev_Family = detected_family; Prev_Bias = detected_bias; Prev_Strength = detected_strength; Mode_Confirmation_Count = 1; } } else { Mode_Confirmation_Count = 0; Current_State = detected_state; } UpdateLabels(); } //+------------------------------------------------------------------+ void MarkRunners() { double current = MidPrice(); for(int i=0; i OpenPositions[i].distance_from_current) { PositionRec tmp = OpenPositions[i]; OpenPositions[i] = OpenPositions[j]; OpenPositions[j] = tmp; } } } 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); int idx = -1; for(int j=0; j= 0 && OpenPositions[idx].is_runner) continue; bool should_close = false; if(is_buy && IsBearBias()) should_close = true; if(!is_buy && IsBullBias()) should_close = true; if(should_close) { if(Trade.PositionClose(ticket)) ClosedByReversal++; } } } //+------------------------------------------------------------------+ // Direction filter core bool IsDirectionAllowed(bool is_buy) { if(!Use_Market_Mode_Filter) return true; if(Current_Family == FAMILY_TRENDING) { if(Current_State == STATE_REVERSAL_CONFIRMED) { if(IsBullBias() && !is_buy) return false; if(IsBearBias() && is_buy) return false; return true; } if(Current_State == STATE_PULLBACK || Current_State == STATE_DEEP_RETRACEMENT) { if(IsBullBias()) { if(!Bull_MA50_Reclaimed()) return (!is_buy); // SELLS ONLY return is_buy; } if(IsBearBias()) { if(!Bear_MA50_Reclaimed()) return (is_buy); // BUYS ONLY return (!is_buy); } } if(Current_State == STATE_CONTINUATION) { if(IsBullBias() && !is_buy) return false; if(IsBearBias() && is_buy) return false; return true; } return true; // reversal attempt/transitional trend } // Range/Chop/Transitional: allow both; setups will handle logic 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 + "|" + FamilyToText(Current_Family) + "|" + BiasToText(Current_Bias) + "|" + StrengthToText(Current_Strength) + "|" + StateToText(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_family = Current_Family; OpenPositions[size].entry_bias = Current_Bias; OpenPositions[size].entry_strength = Current_Strength; OpenPositions[size].distance_from_current = 0; } } //+------------------------------------------------------------------+ 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(); // periodic level refresh static int tick_count = 0; tick_count++; if(tick_count >= 100) { CalculateLevels(); tick_count = 0; } UpdateModeAndState(); ManagePositions(); double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double current = (bid + ask) / 2.0; double previous = iClose(_Symbol, PERIOD_CURRENT, 1); double buffer = MA_Touch_Buffer * _Point; //================================================================= // SETUPS — same core set, now direction filtered by state/action //================================================================= // 1) Trend pullback / deep retracement: countertrend-only until MA50 reclaim/reject if(Current_Family == FAMILY_TRENDING && (Current_State == STATE_PULLBACK || Current_State == STATE_DEEP_RETRACEMENT)) { bool bull = IsBullBias(); bool bear = IsBearBias(); bool allowTrendAgain = (bull && Bull_MA50_Reclaimed()) || (bear && Bear_MA50_Reclaimed()); if(!allowTrendAgain) { // Countertrend mean reversion entries if(Stoch_Extreme_Warning || Stoch_Reject_Warning || Warning_Confluence_3Plus) { if(bull) OpenTrade(false, bid, "PB-COUNTER-SELL", SETUP_MEAN_REV); if(bear) OpenTrade(true, ask, "PB-COUNTER-BUY", SETUP_MEAN_REV); } // Fib/MFIB rejects during pullback if(Fib_Reject_Warning || MFIB_Reject_Warning) { if(bull) OpenTrade(false, bid, (MFIB_Reject_Warning ? "MFIB-REJECT-SELL" : "FIB-REJECT-SELL"), SETUP_FIB_REJECT); if(bear) OpenTrade(true, ask, (MFIB_Reject_Warning ? "MFIB-REJECT-BUY" : "FIB-REJECT-BUY"), SETUP_FIB_REJECT); } // MA reject if(MA_Reject_Warning) { if(bull) OpenTrade(false, bid, "MA-REJECT-SELL", SETUP_CTRL_PULLBACK); if(bear) OpenTrade(true, ask, "MA-REJECT-BUY", SETUP_CTRL_PULLBACK); } } else { // Trend direction re-enabled once MA50 reclaim/reject confirms if(bull) OpenTrade(true, ask, "MA50-RECLAIM-BUY", SETUP_MA50_BOUNCE); if(bear) OpenTrade(false, bid, "MA50-RECLAIM-SELL", SETUP_MA50_BOUNCE); } } // 2) Trend continuation setups if(Current_Family == FAMILY_TRENDING && 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); // MA50 bounce if(MathAbs(current - MA_Current[3]) <= buffer) { OpenTrade(true, ask, "MA50-BOUNCE↑", SETUP_MA50_BOUNCE); OpenTrade(false, bid, "MA50-BOUNCE↓", SETUP_MA50_BOUNCE); } // MA140 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 = (Current_ATR > 0.0) ? (MathAbs(current - MA_Current[2]) / Current_ATR < 0.7) : false; 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); } // 3) Range setups if(Current_Family == FAMILY_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); // MFIB reject inside range edges => higher confidence if(MFIB_Reject_Warning && (Stoch_Reject_Warning || Stoch_Extreme_Warning || Warning_Confluence_3Plus)) { if(current <= MFIB_Level_050) OpenTrade(true, ask, "RANGE-MFIB-BUY", SETUP_RANGE_ENGINE); if(current >= MFIB_Level_050) OpenTrade(false, bid, "RANGE-MFIB-SELL", SETUP_RANGE_ENGINE); } } // 4) Chop handling if(Current_Family == FAMILY_CHOP) { if(Stoch_Extreme_Warning || Stoch_Reject_Warning || Fib_Reject_Warning || MFIB_Reject_Warning || Warning_Confluence_3Plus) { if(Stoch_K_Current <= Stoch_Low) OpenTrade(true, ask, "CHOP-REV-BUY", SETUP_MEAN_REV); if(Stoch_K_Current >= Stoch_High) OpenTrade(false, bid, "CHOP-REV-SELL", SETUP_MEAN_REV); } } } //+------------------------------------------------------------------+