//+------------------------------------------------------------------+ //| QuarterTheory_VIZION_MarketMode_v4.0.mq5 | //| MARKET MODE SYSTEM | INTELLIGENT SETUP FILTERING | //| BULL/BEAR/TREND/CHOP/RANGING | Break/Reclaim/Reject Logic | //+------------------------------------------------------------------+ #property copyright "QuarterTheory x VIZION - Market Mode v4.0" #property version "4.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 group "=== MARKET MODE SYSTEM ===" input bool Use_Market_Mode_Filter = true; // Enable market mode filtering input int Mode_Confirmation_Bars = 3; // Bars to confirm mode change input double Chop_ATR_Threshold = 0.5; // ATR threshold for chop detection input double Range_Price_Threshold = 0.3; // Price range % for ranging market input group "=== MA SYSTEM ===" input int MA_1 = 7; // Heartbeat (primary bias) 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 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, // Strong bullish trending MODE_BULL_TREND, // Bullish trending MODE_BEAR_TREND, // Bearish trending MODE_STRONG_BEAR_TREND, // Strong bearish trending MODE_CHOPPY, // Choppy/whipsaw market MODE_RANGING, // Range-bound market MODE_TRANSITIONAL // Transitioning between modes }; enum PRICE_ACTION { PA_CLEAN_BREAK, // Clean break through level PA_RETEST, // Retesting broken level PA_RECLAIM, // Reclaiming lost level PA_REJECT, // Rejection from level PA_CONSOLIDATION, // Consolidating at level PA_NONE // No specific action }; 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; double Stoch_K_Previous = 0; double Stoch_D_Current = 0; double Stoch_D_Previous = 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 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; int Mode_Confirmation_Count = 0; // Price action states for key levels PRICE_ACTION MA_7_Action = PA_NONE; PRICE_ACTION MA_50_Action = PA_NONE; PRICE_ACTION MA_140_Action = PA_NONE; PRICE_ACTION MA_230_Action = PA_NONE; PRICE_ACTION MA_500_Action = PA_NONE; PRICE_ACTION MFIB_50_Action = PA_NONE; PRICE_ACTION MFIB_618_Action = PA_NONE; PRICE_ACTION Stoch_50_Action = PA_NONE; PRICE_ACTION Stoch_35_Action = PA_NONE; PRICE_ACTION Stoch_65_Action = PA_NONE; // Tracking struct LevelState { double price; bool was_above; datetime last_cross; int cross_count; }; LevelState MA7_State, MA50_State, MA140_State, MA230_State, MA500_State; LevelState MFIB50_State, MFIB618_State; LevelState Stoch50_State, Stoch35_State, Stoch65_State; struct Position { ulong ticket; double entry; double original_lot; bool is_buy; bool partial_tp_hit; bool be_set; bool trailing_active; SETUP_TYPE setup_type; string setup_name; MARKET_MODE entry_mode; }; Position OpenPositions[]; int TodayTrades = 0; int BuyTrades = 0; int SellTrades = 0; int ClosedByMode = 0; int SetupCount[17]; datetime LastEntryTime[17]; //+------------------------------------------------------------------+ int OnInit() { Print("========================================"); Print("MARKET MODE SYSTEM v4.0"); Print("INTELLIGENT SETUP FILTERING"); Print("BULL/BEAR/TREND/CHOP/RANGING"); 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); InitializeLevelStates(); CalculateLevels(); if(Show_Levels) DrawLevels(); Print("Market Mode Filter: ", Use_Market_Mode_Filter ? "ON" : "OFF"); Print("Break/Reclaim/Reject Logic: ACTIVE"); 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, "Arrow_"); ObjectsDeleteAll(0, "ModeLabel"); ObjectsDeleteAll(0, "ActionLabel"); Print("Buys:", BuyTrades, " | Sells:", SellTrades, " | Closed by Mode:", ClosedByMode); } //+------------------------------------------------------------------+ void InitializeLevelStates() { double current = SymbolInfoDouble(_Symbol, SYMBOL_BID); MA7_State.price = 0; MA7_State.was_above = true; MA7_State.last_cross = 0; MA7_State.cross_count = 0; MA50_State = MA7_State; MA140_State = MA7_State; MA230_State = MA7_State; MA500_State = MA7_State; MFIB50_State = MA7_State; MFIB618_State = MA7_State; Stoch50_State = MA7_State; Stoch35_State = MA7_State; Stoch65_State = MA7_State; } //+------------------------------------------------------------------+ 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); } } //+------------------------------------------------------------------+ PRICE_ACTION DetectPriceAction(double current, double previous, double level, LevelState &state) { bool currently_above = current > level; bool previously_above = previous > level; double buffer = MA_Touch_Buffer * _Point; bool at_level = MathAbs(current - level) <= buffer; // Update state if(currently_above != previously_above) { state.last_cross = TimeCurrent(); state.cross_count++; state.was_above = previously_above; } datetime now = TimeCurrent(); int bars_since_cross = (int)((now - state.last_cross) / PeriodSeconds(PERIOD_CURRENT)); // Detect actions if(!previously_above && currently_above && bars_since_cross <= 3) return PA_CLEAN_BREAK; // Clean break up if(previously_above && !currently_above && bars_since_cross <= 3) return PA_CLEAN_BREAK; // Clean break down if(currently_above && !state.was_above && bars_since_cross > 3 && bars_since_cross < 10) return PA_RECLAIM; // Reclaiming from below if(!currently_above && state.was_above && bars_since_cross > 3 && bars_since_cross < 10) return PA_RECLAIM; // Reclaiming from above if(at_level && state.cross_count > 0 && bars_since_cross < 20) return PA_RETEST; // Retesting level if(at_level && ((previously_above && !currently_above) || (!previously_above && currently_above))) return PA_REJECT; // Rejection if(at_level && state.cross_count >= 3 && bars_since_cross > 10) return PA_CONSOLIDATION; // Consolidating return PA_NONE; } //+------------------------------------------------------------------+ void UpdatePriceActions() { double current = SymbolInfoDouble(_Symbol, SYMBOL_BID); double previous = iClose(_Symbol, PERIOD_CURRENT, 1); // MA Actions MA_7_Action = DetectPriceAction(current, previous, MA_Current[0], MA7_State); MA_50_Action = DetectPriceAction(current, previous, MA_Current[3], MA50_State); MA_140_Action = DetectPriceAction(current, previous, MA_Current[4], MA140_State); MA_230_Action = DetectPriceAction(current, previous, MA_Current[5], MA230_State); MA_500_Action = DetectPriceAction(current, previous, MA_Current[6], MA500_State); // MFIB Actions MFIB_50_Action = DetectPriceAction(current, previous, MFIB_Level_050, MFIB50_State); MFIB_618_Action = DetectPriceAction(current, previous, MFIB_Level_618, MFIB618_State); // Stoch Actions Stoch_50_Action = DetectPriceAction(Stoch_K_Current, Stoch_K_Previous, 50, Stoch50_State); Stoch_35_Action = DetectPriceAction(Stoch_K_Current, Stoch_K_Previous, 35, Stoch35_State); Stoch_65_Action = DetectPriceAction(Stoch_K_Current, Stoch_K_Previous, 65, Stoch65_State); } //+------------------------------------------------------------------+ MARKET_MODE DetermineMarketMode() { double current = SymbolInfoDouble(_Symbol, SYMBOL_BID); // Trend strength indicators 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]; // MA alignment (trending) 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]); // Range detection 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; // Chop detection bool ma_clustered = (MathAbs(MA_Current[0] - MA_Current[3]) / Current_ATR < Chop_ATR_Threshold); int cross_count = MA7_State.cross_count + MA50_State.cross_count + MFIB50_State.cross_count; bool is_choppy = (ma_clustered && cross_count > 5) || (Current_ADX < 20); // MFIB position bool above_mfib_618 = current > MFIB_Level_618; bool below_mfib_382 = current < MFIB_Level_382; // Stoch confirmation bool stoch_trending_up = (Stoch_K_Current > Stoch_D_Current) && (Stoch_K_Current > Stoch_K_Previous); bool stoch_trending_down = (Stoch_K_Current < Stoch_D_Current) && (Stoch_K_Current < Stoch_K_Previous); // Determine mode if(is_choppy) return MODE_CHOPPY; if(is_ranging && !mas_aligned_bull && !mas_aligned_bear) return MODE_RANGING; // Strong trending conditions if(mas_aligned_bull && ma7_above_230 && above_mfib_618 && stoch_trending_up && Current_ADX > 25) return MODE_STRONG_BULL_TREND; if(mas_aligned_bear && ma7_below_230 && below_mfib_382 && stoch_trending_down && Current_ADX > 25) return MODE_STRONG_BEAR_TREND; // Regular trending if(mas_aligned_bull && ma7_above_140 && Current_ADX > 20) return MODE_BULL_TREND; if(mas_aligned_bear && ma7_below_140 && Current_ADX > 20) return MODE_BEAR_TREND; return MODE_TRANSITIONAL; } //+------------------------------------------------------------------+ void UpdateMarketMode() { MARKET_MODE detected_mode = DetermineMarketMode(); if(detected_mode != Current_Mode) { if(detected_mode == Previous_Mode) { Mode_Confirmation_Count++; if(Mode_Confirmation_Count >= Mode_Confirmation_Bars) { MARKET_MODE old_mode = Current_Mode; Current_Mode = detected_mode; Mode_Confirmation_Count = 0; Print(">>> MODE CHANGE: ", EnumToString(old_mode), " → ", EnumToString(Current_Mode)); if(Use_Market_Mode_Filter) CloseInvalidPositions(); } } else { Previous_Mode = detected_mode; Mode_Confirmation_Count = 1; } } else { Mode_Confirmation_Count = 0; } UpdateModeLabel(); UpdateActionLabels(); } //+------------------------------------------------------------------+ void UpdateModeLabel() { 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 text = ""; color mode_color = clrYellow; switch(Current_Mode) { case MODE_STRONG_BULL_TREND: text = "MODE: STRONG BULL TREND ↑↑"; mode_color = clrLime; break; case MODE_BULL_TREND: text = "MODE: BULL TREND ↑"; mode_color = clrGreenYellow; break; case MODE_BEAR_TREND: text = "MODE: BEAR TREND ↓"; mode_color = clrOrange; break; case MODE_STRONG_BEAR_TREND: text = "MODE: STRONG BEAR TREND ↓↓"; mode_color = clrRed; break; case MODE_CHOPPY: text = "MODE: CHOPPY ⚡"; mode_color = clrViolet; break; case MODE_RANGING: text = "MODE: RANGING ↔↔"; mode_color = clrAqua; break; case MODE_TRANSITIONAL: text = "MODE: TRANSITIONAL ~"; mode_color = clrYellow; break; } ObjectSetString(0, "ModeLabel", OBJPROP_TEXT, text); ObjectSetInteger(0, "ModeLabel", OBJPROP_COLOR, mode_color); ObjectSetInteger(0, "ModeLabel", OBJPROP_FONTSIZE, 12); } //+------------------------------------------------------------------+ void UpdateActionLabels() { string actions = ""; if(MA_50_Action != PA_NONE) actions += "MA50:" + EnumToString(MA_50_Action) + " | "; if(MA_500_Action != PA_NONE) actions += "MA500:" + EnumToString(MA_500_Action) + " | "; if(MFIB_618_Action != PA_NONE) actions += "MFIB618:" + EnumToString(MFIB_618_Action) + " | "; if(Stoch_50_Action != PA_NONE) actions += "STOCH50:" + EnumToString(Stoch_50_Action); if(actions != "") { ObjectDelete(0, "ActionLabel"); ObjectCreate(0, "ActionLabel", OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, "ActionLabel", OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, "ActionLabel", OBJPROP_XDISTANCE, 10); ObjectSetInteger(0, "ActionLabel", OBJPROP_YDISTANCE, 50); ObjectSetString(0, "ActionLabel", OBJPROP_TEXT, actions); ObjectSetInteger(0, "ActionLabel", OBJPROP_COLOR, clrWhite); ObjectSetInteger(0, "ActionLabel", OBJPROP_FONTSIZE, 10); } } //+------------------------------------------------------------------+ void CloseInvalidPositions() { for(int i=PositionsTotal()-1; i>=0; i--) { if(PositionGetTicket(i) == 0) continue; if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue; if(PositionGetInteger(POSITION_MAGIC) != MagicNumber) continue; bool is_buy = PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY; bool should_close = false; // Close longs in bear trends if(is_buy && (Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND)) should_close = true; // Close shorts in bull trends if(!is_buy && (Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND)) should_close = true; // Close trend trades in choppy/ranging if((Current_Mode == MODE_CHOPPY || Current_Mode == MODE_RANGING)) { // Keep mean reversion and range setups, close trend setups int idx = -1; ulong ticket = PositionGetTicket(i); for(int j=0; j= 0) { SETUP_TYPE setup = OpenPositions[idx].setup_type; if(setup != SETUP_MEAN_REV && setup != SETUP_RANGE_ENGINE && setup != SETUP_FIB_REJECT && setup != SETUP_CTRL_PULLBACK) should_close = true; } } if(should_close) { ulong ticket = PositionGetTicket(i); if(Trade.PositionClose(ticket)) { ClosedByMode++; Print("✂ MODE CLOSE: ", is_buy ? "BUY" : "SELL", " | Mode: ", EnumToString(Current_Mode)); } } } } //+------------------------------------------------------------------+ bool IsSetupValidForMode(SETUP_TYPE setup, bool is_buy) { if(!Use_Market_Mode_Filter) return true; // Mode-specific setup allowances switch(Current_Mode) { case MODE_STRONG_BULL_TREND: // Only bullish setups in strong bull if(!is_buy) return false; // Allow trending setups if(setup == SETUP_MA14_CROSS || setup == SETUP_MAGNET_WALK || setup == SETUP_STAIRCASE_ADV || setup == SETUP_FIB_BREAK) return true; break; case MODE_BULL_TREND: // Prefer longs, allow some shorts on rejection if(!is_buy && (MA_500_Action != PA_REJECT && MFIB_618_Action != PA_REJECT)) return false; // Most setups allowed return true; case MODE_BEAR_TREND: // Prefer shorts, allow some longs on rejection if(is_buy && (MA_500_Action != PA_REJECT && MFIB_618_Action != PA_REJECT)) return false; return true; case MODE_STRONG_BEAR_TREND: // Only bearish setups if(is_buy) return false; if(setup == SETUP_MA14_CROSS || setup == SETUP_MAGNET_WALK || setup == SETUP_STAIRCASE_ADV || setup == SETUP_FIB_BREAK) return true; break; case MODE_CHOPPY: // Only counter-trend and mean reversion in chop if(setup == SETUP_MEAN_REV || setup == SETUP_CTRL_PULLBACK || setup == SETUP_FIB_REJECT) return true; return false; case MODE_RANGING: // Range and mean reversion setups only 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; case MODE_TRANSITIONAL: // Conservative during transition - only pullbacks and bounces if(setup == SETUP_CTRL_PULLBACK || setup == SETUP_MA50_BOUNCE || setup == SETUP_MA140_BOUNCE || setup == SETUP_MEAN_REV) return true; return false; } return false; } //+------------------------------------------------------------------+ void UpdateIndicators() { for(int i=0; i<10; i++) { double curr[1], prev[1]; if(CopyBuffer(MA_Handles[i], 0, 0, 1, curr) > 0) MA_Current[i] = curr[0]; if(CopyBuffer(MA_Handles[i], 0, 1, 1, prev) > 0) MA_Previous[i] = prev[0]; } double k_curr[1], k_prev[1], d_curr[1], d_prev[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, SIGNAL_LINE, 0, 1, d_curr) > 0) Stoch_D_Current = d_curr[0]; if(CopyBuffer(Stoch_Handle, SIGNAL_LINE, 1, 1, d_prev) > 0) Stoch_D_Previous = d_prev[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]; } //+------------------------------------------------------------------+ 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 mode_text = EnumToString(Current_Mode); string comment = setup_name + "|" + mode_text; 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].setup_type = setup_type; OpenPositions[size].setup_name = setup_name; OpenPositions[size].entry_mode = Current_Mode; Print("✓ ", setup_name, " ", buy ? "BUY" : "SELL", " [", CountSetupTrades(setup_type), "/", Max_Trades_Per_Setup, "] | Mode:", mode_text); } } //+------------------------------------------------------------------+ 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; } } } 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; } } } 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(); UpdatePriceActions(); 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; //================================================================= // MARKET MODE FILTERED SETUPS //================================================================= // SETUP 1: MA14 CROSS (Trending markets only) if(Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND || Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) { 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); } // SETUP 2-5: MA BOUNCES (All modes except choppy) if(Current_Mode != MODE_CHOPPY) { if(MathAbs(current - MA_Current[3]) <= buffer) { if(MA_50_Action == PA_RETEST || MA_50_Action == PA_RECLAIM) { OpenTrade(true, ask, "MA50-BOUNCE↑", SETUP_MA50_BOUNCE); OpenTrade(false, bid, "MA50-BOUNCE↓", SETUP_MA50_BOUNCE); } } if(MathAbs(current - MA_Current[4]) <= buffer) { if(MA_140_Action == PA_RETEST || MA_140_Action == PA_RECLAIM) { OpenTrade(true, ask, "MA140-BOUNCE↑", SETUP_MA140_BOUNCE); OpenTrade(false, bid, "MA140-BOUNCE↓", SETUP_MA140_BOUNCE); } } if(MathAbs(current - MA_Current[5]) <= buffer) { if(MA_230_Action == PA_RETEST || MA_230_Action == PA_RECLAIM) { OpenTrade(true, ask, "MA230-BOUNCE↑", SETUP_MA230_BOUNCE); OpenTrade(false, bid, "MA230-BOUNCE↓", SETUP_MA230_BOUNCE); } } if(MathAbs(current - MA_Current[6]) <= buffer) { if(MA_500_Action == PA_RETEST || MA_500_Action == PA_RECLAIM) { OpenTrade(true, ask, "MA500-TOUCH↑", SETUP_MA500_TOUCH); OpenTrade(false, bid, "MA500-TOUCH↓", SETUP_MA500_TOUCH); } } } // SETUP 6-8: FIB TRADING for(int i=1; i<6; i++) { if(MathAbs(current - PriceLevels[i]) <= buffer) { // FIB BREAK - trending markets if(Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND || Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) { if(previous < PriceLevels[i]) OpenTrade(true, ask, "FIB-BREAK↑", SETUP_FIB_BREAK); if(previous > PriceLevels[i]) OpenTrade(false, bid, "FIB-BREAK↓", SETUP_FIB_BREAK); } // FIB RECLAIM - transitional/ranging if(Current_Mode == MODE_TRANSITIONAL || Current_Mode == MODE_RANGING) { if(previous < PriceLevels[i] && current > PriceLevels[i]) OpenTrade(true, ask, "FIB-RECLAIM↑", SETUP_FIB_RECLAIM); if(previous > PriceLevels[i] && current < PriceLevels[i]) OpenTrade(false, bid, "FIB-RECLAIM↓", SETUP_FIB_RECLAIM); } // FIB REJECT - ranging/choppy if(Current_Mode == MODE_RANGING || Current_Mode == MODE_CHOPPY) { if(Stoch_K_Current > 65) OpenTrade(false, bid, "FIB-REJECT↓", SETUP_FIB_REJECT); if(Stoch_K_Current < 35) OpenTrade(true, ask, "FIB-REJECT↑", SETUP_FIB_REJECT); } } } // SETUP 9: MAGNET WALK (Trending only) if(Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND || Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) { 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); } // SETUP 10: STAIRCASE (Trending only) if(Current_Mode != MODE_CHOPPY && Current_Mode != MODE_RANGING) { 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); } // SETUP 11: CONTROLLED PULLBACK (All modes) bool near_ma = MathAbs(current - MA_Current[3]) / Current_ATR < 1.5; if(near_ma && Stoch_50_Action == PA_RECLAIM) { if(Stoch_K_Previous > 55 && Stoch_K_Current < 50) OpenTrade(true, ask, "CTRL-PULLBACK↑", SETUP_CTRL_PULLBACK); if(Stoch_K_Previous < 45 && Stoch_K_Current > 50) OpenTrade(false, bid, "CTRL-PULLBACK↓", SETUP_CTRL_PULLBACK); } // SETUP 12: TIMEFRAME RESET (Transitional/trending) if(Current_Mode != MODE_CHOPPY && Current_Mode != MODE_RANGING) { if(Stoch_35_Action == PA_REJECT && MA_Current[0] > MA_Current[6]) OpenTrade(true, ask, "TF-RESET↑", SETUP_TF_RESET); if(Stoch_65_Action == PA_REJECT && MA_Current[0] < MA_Current[6]) OpenTrade(false, bid, "TF-RESET↓", SETUP_TF_RESET); } // SETUP 13: MFIB LADDER (Trending) if(Current_Mode == MODE_BULL_TREND || Current_Mode == MODE_STRONG_BULL_TREND || Current_Mode == MODE_BEAR_TREND || Current_Mode == MODE_STRONG_BEAR_TREND) { if(MathAbs(current - MFIB_Level_618) <= buffer && MFIB_618_Action == PA_CLEAN_BREAK) { if(previous <= MFIB_Level_618) OpenTrade(true, ask, "MFIB-LADDER618↑", SETUP_MFIB_LADDER); if(previous >= MFIB_Level_618) OpenTrade(false, bid, "MFIB-LADDER618↓", SETUP_MFIB_LADDER); } } // SETUP 14: MFIB PRESS (Trending) if(Current_Mode != MODE_CHOPPY && Current_Mode != MODE_RANGING) { bool near_mfib = MathAbs(current - MFIB_Level_050) / Current_ATR < 1.2; if(near_mfib && MFIB_50_Action == PA_RETEST) { 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); } } // SETUP 15: MEAN REVERSION (Choppy/ranging preferred) bool near_230 = MathAbs(current - MA_Current[5]) / Current_ATR < 1.0; if(near_230) { if(Stoch_K_Current < 30 && MA_230_Action == PA_REJECT) OpenTrade(true, ask, "MEAN-REV-BUY", SETUP_MEAN_REV); if(Stoch_K_Current > 70 && MA_230_Action == PA_REJECT) OpenTrade(false, bid, "MEAN-REV-SELL", SETUP_MEAN_REV); } // SETUP 16: RANGE ENGINE (Ranging only) 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); } } //+------------------------------------------------------------------+