//+------------------------------------------------------------------+ //| QuarterTheory_VIZION_v7_PATTERNS.mq5 | //| + CANDLESTICK PATTERNS: Confirmation for Structure Signals | //| PRAISE SYSTEM: 8 Trend Signals | WAR SURVIVOR: MFIB Partials | //+------------------------------------------------------------------+ #property copyright "QuarterTheory x VIZION" #property version "7.00" #property strict #include CTrade Trade; //================ CORE STRUCTURES ==================// struct SignalParams { int sl_points, be_points, trail_points, tp_points; int partial_tp; double partial_pct; }; struct IndicatorData { double ma[10], ma_prev[10], ma_prev2[10]; double stoch_k, stoch_k_prev, stoch_k_prev2; double stoch_d; double atr, adx; }; struct MFIBLevels { double high, low; double level_236, level_382, level_050, level_618, level_786; }; struct PositionRecord { ulong ticket; double entry, original_lot, close_price, last_mfib_partial_price; bool is_buy, partial_tp_hit, be_set, trailing_active, is_runner; bool closed_at_sl, closed_at_be; int setup_type, category, entry_family, entry_bias, entry_strength; int mfib_partials_taken; double distance_from_current; string setup_name; }; struct ClosureRecord { int setup_type, category; bool was_buy, closed_at_sl, closed_at_be; double close_price; datetime close_time; }; struct CandlePatterns { // Bullish Patterns bool bull_engulfing, bull_hammer, bull_morning_star; bool bull_piercing, bull_three_white; // Bearish Patterns bool bear_engulfing, bear_shooting_star, bear_evening_star; bool bear_dark_cloud, bear_three_black; // Reversal Indicators bool doji, spinning_top, harami; // Counts int bullish_count, bearish_count, reversal_count; // Pattern Strength bool strong_bullish_pattern, strong_bearish_pattern; bool reversal_warning; }; struct Warnings { bool stoch_extreme, stoch_reject, stoch_level_cross; bool ma7_cross_14, ma7_cross_21, ma50_break; bool fib_reject, fib_reclaim, fib_break; bool mfib_reject, mfib_reclaim, mfib_break; bool ma_reject, ma_reclaim, ma_break; bool band_snap, ma50, ma140, ma230, ma500; bool pullback, retracement; bool ma14_magnet, fib_break_confirmed, mfib_break_confirmed; bool strong_ma_bounce, trend_resumption; // Pattern-enhanced warnings bool pattern_reversal_warn; bool pattern_rejection_confirm; int confluence_count; bool confluence_3plus; }; struct Praise { bool triple_magnet, power_couple; bool mfib_staircase, mfib_express, mfib_breakout; bool ma_stack, clean_reclaim, multi_breakout; // Pattern-enhanced praise bool pattern_confirmation; bool pattern_momentum_align; int count; }; //================ 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, STATE_PULLBACK = 1, STATE_DEEP_RETRACEMENT = 2, STATE_REVERSAL_ATTEMPT = 3, STATE_REVERSAL_CONFIRMED = 4, STATE_RANGE_MID_DRIFT = 10, STATE_RANGE_EDGE_TEST = 11, STATE_RANGE_REJECTION = 12, STATE_RANGE_BREAK_ATTEMPT = 13, STATE_RANGE_BREAK_CONFIRMED = 14, 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, SETUP_PULLBACK_COUNTER = 17, SETUP_RETRACEMENT_COUNTER = 18 }; enum TRADE_CATEGORY { CATEGORY_CONTINUATION = 0, CATEGORY_COUNTER_TREND = 1 }; //================ 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 "=== CANDLESTICK PATTERNS ===" input bool Use_Pattern_Detection = true; input bool Pattern_Boost_Praise = true; input bool Pattern_Enhance_Warnings = true; input double Pattern_Praise_Multiplier = 1.3; input double Pattern_Size_Threshold = 0.3; // Min body size vs ATR for pattern validity input group "=== REVERSAL CONFIRMATION ===" input bool Only_Close_On_Full_Reversal = true; input group "=== MA SYSTEM ===" input int MA_1 = 7, MA_2 = 14, MA_3 = 21, MA_4 = 50, MA_5 = 140; input int MA_6 = 230, MA_7 = 500, MA_8 = 1000, MA_9 = 1100, 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; input double Stoch_Extreme_Low = 15.0; input double Stoch_High = 70.0; input double Stoch_Low = 30.0; input group "=== MOVING FIBONACCI ===" input int MFIB_Lookback = 500; input bool Use_MFIB_382_Bias = true; input group "=== FIBONACCI ===" input int Lookback_Bars = 200; input bool Show_Levels = true; input group "=== SIGNAL PARAMETERS ===" input int Continuation_SL_Points = 150; input int Continuation_BreakEven = 300; input int Continuation_Trail = 300; input int Continuation_TP = 4000; input int Continuation_Partial_TP = 900; input double Continuation_Partial_Pct = 33.0; input int Counter_SL_Points = 50; input int Counter_BreakEven = 25; input int Counter_Trail = 150; input int Counter_TP = 3000; input int Counter_Partial_TP = 100; input double Counter_Partial_Pct = 50.0; input group "=== WAR SURVIVOR & PRAISE ===" input bool Use_MFIB_Partials = true; input double MFIB_Partial_Percent = 25.0; input int MFIB_Partial_Min_Profit = 30; input double War_Survivor_Multiplier = 2.5; input bool Use_Praise_System = true; input double Praise_Multiplier_Strong = 1.5; input double Praise_Multiplier_Supreme = 2.0; input int Praise_Tight_Trail = 100; input bool Pause_Counter_On_Praise = true; input bool Reduce_Continuation_Warn = true; input bool Max_Aggression_Mode = true; input group "=== OTHER SETTINGS ===" input double Band_Snap_ATR_Multiplier = 2.0; input bool Allow_Re_Entry = true; input int Re_Entry_Cooldown_Bars = 5; //================ GLOBALS ==================// int Stoch_Handle, ATR_Handle, ADX_Handle; int MA_Handles[10]; double PriceLevels[7]; IndicatorData Indicators; MFIBLevels MFIB; PositionRecord OpenPositions[]; ClosureRecord RecentClosures[10]; int ClosureIndex = 0; Warnings Warn; Praise PraiseSignals; CandlePatterns Patterns; MODE_FAMILY Current_Family, Prev_Family; TREND_BIAS Current_Bias, Prev_Bias, MFIB_Bias; TREND_STRENGTH Current_Strength, Prev_Strength; PRICE_STATE Current_State; int Mode_Confirmation_Count, Reversal_Confirm_Counter; int TodayTrades = 0, BuyTrades = 0, SellTrades = 0, ClosedByReversal = 0; int SetupCount[19]; datetime LastEntryTime[19]; double Stoch_Levels[5] = {20.0, 35.0, 50.0, 65.0, 80.0}; int MA_Periods[10] = {7, 14, 21, 50, 140, 230, 500, 1000, 1100, 1300}; //================ HELPERS ==================// double Mid() { return (SymbolInfoDouble(_Symbol, SYMBOL_BID) + SymbolInfoDouble(_Symbol, SYMBOL_ASK)) / 2.0; } bool Near(double price, double level, double tolPts) { return MathAbs(price - level) <= tolPts * _Point; } bool StochUp() { return (Indicators.stoch_k_prev < Indicators.stoch_d && Indicators.stoch_k >= Indicators.stoch_d); } bool StochDn() { return (Indicators.stoch_k_prev > Indicators.stoch_d && Indicators.stoch_k <= Indicators.stoch_d); } bool IsBull() { return (Current_Bias == BIAS_BULL); } bool IsBear() { return (Current_Bias == BIAS_BEAR); } bool BullMA50Reclaim() { bool rec = (Indicators.ma_prev[0] <= Indicators.ma_prev[3]) && (Indicators.ma[0] > Indicators.ma[3]); double low0 = iLow(_Symbol, PERIOD_CURRENT, 0), close0 = iClose(_Symbol, PERIOD_CURRENT, 0); bool rej = (low0 <= Indicators.ma[3] && close0 > Indicators.ma[3] && (StochUp() || Indicators.stoch_k > 50)); return (rec || rej); } bool BearMA50Reclaim() { bool rec = (Indicators.ma_prev[0] >= Indicators.ma_prev[3]) && (Indicators.ma[0] < Indicators.ma[3]); double high0 = iHigh(_Symbol, PERIOD_CURRENT, 0), close0 = iClose(_Symbol, PERIOD_CURRENT, 0); bool rej = (high0 >= Indicators.ma[3] && close0 < Indicators.ma[3] && (StochDn() || Indicators.stoch_k < 50)); return (rec || rej); } void RecordClosure(int setup, int cat, bool was_buy, double close_price, bool at_sl, bool at_be) { RecentClosures[ClosureIndex].setup_type = setup; RecentClosures[ClosureIndex].category = cat; RecentClosures[ClosureIndex].was_buy = was_buy; RecentClosures[ClosureIndex].close_price = close_price; RecentClosures[ClosureIndex].close_time = TimeCurrent(); RecentClosures[ClosureIndex].closed_at_sl = at_sl; RecentClosures[ClosureIndex].closed_at_be = at_be; ClosureIndex = (ClosureIndex + 1) % 10; } bool RecentlyStopped(int setup) { datetime cutoff = TimeCurrent() - 10 * PeriodSeconds(PERIOD_CURRENT); for(int i=0; i<10; i++) { if(RecentClosures[i].setup_type == setup && RecentClosures[i].close_time > cutoff && (RecentClosures[i].closed_at_sl || RecentClosures[i].closed_at_be)) return true; } return false; } //+------------------------------------------------------------------+ //| CANDLESTICK PATTERN DETECTION //+------------------------------------------------------------------+ double CandleBody(int shift) { double open = iOpen(_Symbol, PERIOD_CURRENT, shift); double close = iClose(_Symbol, PERIOD_CURRENT, shift); return MathAbs(close - open); } double CandleRange(int shift) { return iHigh(_Symbol, PERIOD_CURRENT, shift) - iLow(_Symbol, PERIOD_CURRENT, shift); } bool IsBullishCandle(int shift) { return iClose(_Symbol, PERIOD_CURRENT, shift) > iOpen(_Symbol, PERIOD_CURRENT, shift); } bool IsBearishCandle(int shift) { return iClose(_Symbol, PERIOD_CURRENT, shift) < iOpen(_Symbol, PERIOD_CURRENT, shift); } double UpperWick(int shift) { double high = iHigh(_Symbol, PERIOD_CURRENT, shift); double close = iClose(_Symbol, PERIOD_CURRENT, shift); double open = iOpen(_Symbol, PERIOD_CURRENT, shift); return high - MathMax(close, open); } double LowerWick(int shift) { double low = iLow(_Symbol, PERIOD_CURRENT, shift); double close = iClose(_Symbol, PERIOD_CURRENT, shift); double open = iOpen(_Symbol, PERIOD_CURRENT, shift); return MathMin(close, open) - low; } void DetectCandlePatterns() { if(!Use_Pattern_Detection) { ZeroMemory(Patterns); return; } ZeroMemory(Patterns); double atr = Indicators.atr; if(atr <= 0) return; // Get candle data double o0 = iOpen(_Symbol, PERIOD_CURRENT, 0); double h0 = iHigh(_Symbol, PERIOD_CURRENT, 0); double l0 = iLow(_Symbol, PERIOD_CURRENT, 0); double c0 = iClose(_Symbol, PERIOD_CURRENT, 0); double o1 = iOpen(_Symbol, PERIOD_CURRENT, 1); double h1 = iHigh(_Symbol, PERIOD_CURRENT, 1); double l1 = iLow(_Symbol, PERIOD_CURRENT, 1); double c1 = iClose(_Symbol, PERIOD_CURRENT, 1); double o2 = iOpen(_Symbol, PERIOD_CURRENT, 2); double h2 = iHigh(_Symbol, PERIOD_CURRENT, 2); double l2 = iLow(_Symbol, PERIOD_CURRENT, 2); double c2 = iClose(_Symbol, PERIOD_CURRENT, 2); double body0 = CandleBody(0); double body1 = CandleBody(1); double body2 = CandleBody(2); double range1 = CandleRange(1); // Minimum body size requirement double min_body = atr * Pattern_Size_Threshold; //=== BULLISH ENGULFING === if(IsBearishCandle(1) && IsBullishCandle(0)) { if(c0 > o1 && o0 < c1 && body0 > body1 * 1.2 && body0 > min_body) { Patterns.bull_engulfing = true; Patterns.bullish_count++; } } //=== BEARISH ENGULFING === if(IsBullishCandle(1) && IsBearishCandle(0)) { if(c0 < o1 && o0 > c1 && body0 > body1 * 1.2 && body0 > min_body) { Patterns.bear_engulfing = true; Patterns.bearish_count++; } } //=== HAMMER (Bullish) === if(IsBullishCandle(1)) { double lower_wick = LowerWick(1); double upper_wick = UpperWick(1); if(lower_wick > body1 * 2.0 && upper_wick < body1 * 0.5 && body1 > min_body) { Patterns.bull_hammer = true; Patterns.bullish_count++; } } //=== SHOOTING STAR (Bearish) === if(IsBearishCandle(1)) { double upper_wick = UpperWick(1); double lower_wick = LowerWick(1); if(upper_wick > body1 * 2.0 && lower_wick < body1 * 0.5 && body1 > min_body) { Patterns.bear_shooting_star = true; Patterns.bearish_count++; } } //=== MORNING STAR (Bullish) === if(IsBearishCandle(2) && IsBullishCandle(0)) { if(body1 < body2 * 0.3 && body1 < body0 * 0.3 && c0 > (o2 + c2) / 2 && body0 > min_body) { Patterns.bull_morning_star = true; Patterns.bullish_count += 2; // Strong pattern } } //=== EVENING STAR (Bearish) === if(IsBullishCandle(2) && IsBearishCandle(0)) { if(body1 < body2 * 0.3 && body1 < body0 * 0.3 && c0 < (o2 + c2) / 2 && body0 > min_body) { Patterns.bear_evening_star = true; Patterns.bearish_count += 2; // Strong pattern } } //=== PIERCING PATTERN (Bullish) === if(IsBearishCandle(1) && IsBullishCandle(0)) { double midpoint = c1 + (o1 - c1) * 0.5; if(c0 > midpoint && c0 < o1 && o0 < c1 && body0 > min_body) { Patterns.bull_piercing = true; Patterns.bullish_count++; } } //=== DARK CLOUD COVER (Bearish) === if(IsBullishCandle(1) && IsBearishCandle(0)) { double midpoint = o1 + (c1 - o1) * 0.5; if(c0 < midpoint && c0 > o1 && o0 > c1 && body0 > min_body) { Patterns.bear_dark_cloud = true; Patterns.bearish_count++; } } //=== THREE WHITE SOLDIERS (Bullish) === if(IsBullishCandle(2) && IsBullishCandle(1) && IsBullishCandle(0)) { if(c1 > c2 && c0 > c1 && o1 > o2 && o1 < c2 && o0 > o1 && o0 < c1) { if(body0 > min_body && body1 > min_body && body2 > min_body) { Patterns.bull_three_white = true; Patterns.bullish_count += 2; // Very strong } } } //=== THREE BLACK CROWS (Bearish) === if(IsBearishCandle(2) && IsBearishCandle(1) && IsBearishCandle(0)) { if(c1 < c2 && c0 < c1 && o1 < o2 && o1 > c2 && o0 < o1 && o0 > c1) { if(body0 > min_body && body1 > min_body && body2 > min_body) { Patterns.bear_three_black = true; Patterns.bearish_count += 2; // Very strong } } } //=== DOJI (Reversal Warning) === if(body1 < range1 * 0.1 && range1 > min_body) { Patterns.doji = true; Patterns.reversal_count++; } //=== SPINNING TOP (Indecision) === if(body1 < range1 * 0.3 && body1 > range1 * 0.1) { double upper_wick = UpperWick(1); double lower_wick = LowerWick(1); if(upper_wick > body1 && lower_wick > body1) { Patterns.spinning_top = true; Patterns.reversal_count++; } } //=== HARAMI (Reversal) === if(body0 < body1 * 0.5) { if(IsBearishCandle(1) && IsBullishCandle(0) && o0 > c1 && c0 < o1) { Patterns.harami = true; Patterns.reversal_count++; } if(IsBullishCandle(1) && IsBearishCandle(0) && o0 < c1 && c0 > o1) { Patterns.harami = true; Patterns.reversal_count++; } } // Pattern Strength Assessment Patterns.strong_bullish_pattern = (Patterns.bullish_count >= 2) || Patterns.bull_morning_star || Patterns.bull_three_white; Patterns.strong_bearish_pattern = (Patterns.bearish_count >= 2) || Patterns.bear_evening_star || Patterns.bear_three_black; Patterns.reversal_warning = (Patterns.reversal_count >= 1) || Patterns.doji || Patterns.harami; } //+------------------------------------------------------------------+ int OnInit() { Print("========== QuarterTheory VIZION v7 (PATTERNS) =========="); Print("CANDLESTICK PATTERNS: Structure + Pattern Confirmation"); Print("WAR SURVIVOR: 2.5x size + 25% MFIB partials"); Print("PRAISE SYSTEM: 8 Trend Signals + Pattern Boost"); 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); for(int i=0; i<10; i++) MA_Handles[i] = iMA(_Symbol, PERIOD_CURRENT, MA_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, "MFIB_"); Print("Final: B:", BuyTrades, " | S:", SellTrades, " | Reversed:", ClosedByReversal); } //+------------------------------------------------------------------+ void CalculateLevels() { double high = iHigh(_Symbol, PERIOD_CURRENT, 0), low = iLow(_Symbol, PERIOD_CURRENT, 0); for(int i=1; i<=Lookback_Bars; i++) { double h = iHigh(_Symbol, PERIOD_CURRENT, i), l = iLow(_Symbol, PERIOD_CURRENT, i); if(h > high) high = h; if(l < low) low = l; } double range = high - low; PriceLevels[0] = low; for(int i=1; i<6; i++) PriceLevels[i] = low + range * (i==1 ? 0.236 : i==2 ? 0.382 : i==3 ? 0.5 : i==4 ? 0.618 : 0.786); PriceLevels[6] = high; double ath = iHigh(_Symbol, PERIOD_CURRENT, 0), atl = iLow(_Symbol, PERIOD_CURRENT, 0); for(int i=1; i<=MFIB_Lookback; i++) { double h = iHigh(_Symbol, PERIOD_CURRENT, i), l = iLow(_Symbol, PERIOD_CURRENT, i); if(h > ath) ath = h; if(l < atl) atl = l; } MFIB.high = ath; MFIB.low = atl; double mfib_range = ath - atl; MFIB.level_236 = ath - (mfib_range * 0.236); MFIB.level_382 = ath - (mfib_range * 0.382); MFIB.level_050 = ath - (mfib_range * 0.500); MFIB.level_618 = ath - (mfib_range * 0.618); MFIB.level_786 = ath - (mfib_range * 0.786); if(Use_MFIB_382_Bias) { double current = Mid(); if(current > MFIB.level_382) MFIB_Bias = BIAS_BULL; else if(current < MFIB.level_382) MFIB_Bias = BIAS_BEAR; else MFIB_Bias = BIAS_NEUTRAL; } else MFIB_Bias = BIAS_NEUTRAL; } void DrawLevels() { ObjectsDeleteAll(0, "Level_"); ObjectsDeleteAll(0, "MFIB_"); color level_colors[7] = {clrRed, clrOrange, clrYellow, clrLime, clrCyan, clrBlue, clrMagenta}; for(int i=0; i<7; i++) { ObjectCreate(0, "Level_" + IntegerToString(i), OBJ_HLINE, 0, 0, PriceLevels[i]); ObjectSetInteger(0, "Level_" + IntegerToString(i), OBJPROP_COLOR, level_colors[i]); ObjectSetInteger(0, "Level_" + IntegerToString(i), OBJPROP_STYLE, STYLE_DOT); } ObjectCreate(0, "MFIB_382", OBJ_HLINE, 0, 0, MFIB.level_382); ObjectSetInteger(0, "MFIB_382", OBJPROP_COLOR, clrYellow); ObjectSetInteger(0, "MFIB_382", OBJPROP_WIDTH, 2); ObjectCreate(0, "MFIB_618", OBJ_HLINE, 0, 0, MFIB.level_618); ObjectSetInteger(0, "MFIB_618", OBJPROP_COLOR, clrCyan); ObjectSetInteger(0, "MFIB_618", 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) Indicators.ma[i] = curr[0]; if(CopyBuffer(MA_Handles[i], 0, 1, 1, prev) > 0) Indicators.ma_prev[i] = prev[0]; if(CopyBuffer(MA_Handles[i], 0, 2, 1, prev2) > 0) Indicators.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) Indicators.stoch_k = k_curr[0]; if(CopyBuffer(Stoch_Handle, MAIN_LINE, 1, 1, k_prev) > 0) Indicators.stoch_k_prev = k_prev[0]; if(CopyBuffer(Stoch_Handle, MAIN_LINE, 2, 1, k_prev2) > 0) Indicators.stoch_k_prev2 = k_prev2[0]; if(CopyBuffer(Stoch_Handle, SIGNAL_LINE, 0, 1, d_curr) > 0) Indicators.stoch_d = d_curr[0]; double atr[1], adx[1]; if(CopyBuffer(ATR_Handle, 0, 0, 1, atr) > 0) Indicators.atr = atr[0]; if(CopyBuffer(ADX_Handle, 0, 0, 1, adx) > 0) Indicators.adx = adx[0]; } //+------------------------------------------------------------------+ void DetectWarnings() { double current = Mid(), prev = iClose(_Symbol, PERIOD_CURRENT, 1), bufPts = (double)MA_Touch_Buffer; double mfib_levels[5] = {MFIB.level_236, MFIB.level_382, MFIB.level_050, MFIB.level_618, MFIB.level_786}; ZeroMemory(Warn); if(Indicators.stoch_k <= Stoch_Extreme_Low || Indicators.stoch_k >= Stoch_Extreme_High) Warn.stoch_extreme = true; bool k_crossed_d = (Indicators.stoch_k_prev < Indicators.stoch_d && Indicators.stoch_k >= Indicators.stoch_d) || (Indicators.stoch_k_prev > Indicators.stoch_d && Indicators.stoch_k <= Indicators.stoch_d); bool near_key = false; for(int i=0; i<5; i++) if(MathAbs(Indicators.stoch_k - Stoch_Levels[i]) <= 5.0) { near_key = true; break; } if(k_crossed_d && near_key) Warn.stoch_level_cross = true; bool stoch_reject_dn = (StochDn() && Indicators.stoch_k > 50); bool stoch_reject_up = (StochUp() && Indicators.stoch_k < 50); if(stoch_reject_dn || stoch_reject_up || Warn.stoch_level_cross) Warn.stoch_reject = true; bool ma7_crossed_14_dn = (Indicators.ma_prev[0] > Indicators.ma_prev[1]) && (Indicators.ma[0] <= Indicators.ma[1]); bool ma7_crossed_14_up = (Indicators.ma_prev[0] < Indicators.ma_prev[1]) && (Indicators.ma[0] >= Indicators.ma[1]); if(ma7_crossed_14_dn || ma7_crossed_14_up) { Warn.ma7_cross_14 = true; Warn.pullback = true; } bool ma7_crossed_21_dn = (Indicators.ma_prev[0] > Indicators.ma_prev[2]) && (Indicators.ma[0] <= Indicators.ma[2]); bool ma7_crossed_21_up = (Indicators.ma_prev[0] < Indicators.ma_prev[2]) && (Indicators.ma[0] >= Indicators.ma[2]); if(ma7_crossed_21_dn || ma7_crossed_21_up) { Warn.ma7_cross_21 = true; Warn.retracement = true; } bool ma7_broke_50_dn = (Indicators.ma_prev[0] > Indicators.ma_prev[3]) && (Indicators.ma[0] <= Indicators.ma[3]); bool ma7_broke_50_up = (Indicators.ma_prev[0] < Indicators.ma_prev[3]) && (Indicators.ma[0] >= Indicators.ma[3]); if(ma7_broke_50_dn || ma7_broke_50_up) Warn.ma50_break = true; if(Indicators.atr > 0.0) { double distance = MathAbs(current - Indicators.ma[0]); if(distance >= Indicators.atr * Band_Snap_ATR_Multiplier) Warn.band_snap = true; } bool at_fib = false; int fib_idx = -1; for(int i=1; i<6; i++) if(Near(current, PriceLevels[i], bufPts)) { at_fib = true; fib_idx = i; break; } if(at_fib) { if(Warn.stoch_extreme || Warn.stoch_reject || Warn.stoch_level_cross) Warn.fib_reject = true; if((prev < PriceLevels[fib_idx] && current > PriceLevels[fib_idx]) || (prev > PriceLevels[fib_idx] && current < PriceLevels[fib_idx])) Warn.fib_reclaim = true; if(MathAbs(current - PriceLevels[fib_idx]) > bufPts * 1.5) Warn.fib_break = true; } bool at_mfib = false; double mfib_level = 0; for(int i=0; i<5; i++) if(Near(current, mfib_levels[i], bufPts)) { at_mfib = true; mfib_level = mfib_levels[i]; break; } if(at_mfib) { if(Warn.stoch_extreme || Warn.stoch_reject || Warn.stoch_level_cross) Warn.mfib_reject = true; if((prev < mfib_level && current > mfib_level) || (prev > mfib_level && current < mfib_level)) Warn.mfib_reclaim = true; if(MathAbs(current - mfib_level) > bufPts * 1.5) Warn.mfib_break = true; } if(Near(current, Indicators.ma[3], bufPts)) Warn.ma50 = true; if(Near(current, Indicators.ma[4], bufPts)) Warn.ma140 = true; if(Near(current, Indicators.ma[5], bufPts)) Warn.ma230 = true; if(Near(current, Indicators.ma[6], bufPts)) Warn.ma500 = true; if((Warn.ma50 || Warn.ma140 || Warn.ma230 || Warn.ma500) && (Warn.stoch_extreme || Warn.stoch_reject || Warn.stoch_level_cross)) Warn.ma_reject = true; if(Warn.ma50 && ((prev < Indicators.ma[3] && current > Indicators.ma[3]) || (prev > Indicators.ma[3] && current < Indicators.ma[3]))) Warn.ma_reclaim = true; if(Warn.ma140 && ((prev < Indicators.ma[4] && current > Indicators.ma[4]) || (prev > Indicators.ma[4] && current < Indicators.ma[4]))) Warn.ma_reclaim = true; if((Warn.ma50 || Warn.ma140 || Warn.ma230) && MathAbs(current - Indicators.ma[3]) > bufPts * 2) Warn.ma_break = true; // PATTERN-ENHANCED WARNINGS if(Pattern_Enhance_Warnings && Use_Pattern_Detection) { // Reversal patterns confirm warning signals if(Patterns.reversal_warning && (Warn.stoch_extreme || Warn.ma_reject || Warn.fib_reject)) { Warn.pattern_reversal_warn = true; } // Bearish patterns confirm bullish rejections if(IsBull() && Patterns.strong_bearish_pattern && (Warn.ma_reject || Warn.fib_reject || Warn.mfib_reject)) { Warn.pattern_rejection_confirm = true; } // Bullish patterns confirm bearish rejections if(IsBear() && Patterns.strong_bullish_pattern && (Warn.ma_reject || Warn.fib_reject || Warn.mfib_reject)) { Warn.pattern_rejection_confirm = true; } } Warn.confluence_count = 0; if(Warn.stoch_extreme) Warn.confluence_count++; if(Warn.stoch_reject) Warn.confluence_count++; if(Warn.stoch_level_cross) Warn.confluence_count++; if(Warn.ma7_cross_14) Warn.confluence_count++; if(Warn.ma7_cross_21) Warn.confluence_count++; if(Warn.ma50_break) Warn.confluence_count++; if(Warn.fib_reject) Warn.confluence_count++; if(Warn.mfib_reject) Warn.confluence_count++; if(Warn.ma_reject) Warn.confluence_count++; if(Warn.fib_reclaim) Warn.confluence_count++; if(Warn.mfib_reclaim) Warn.confluence_count++; if(Warn.ma_reclaim) Warn.confluence_count++; if(Warn.band_snap) Warn.confluence_count++; if(Warn.ma50) Warn.confluence_count++; if(Warn.ma140) Warn.confluence_count++; if(Warn.ma230) Warn.confluence_count++; if(Warn.ma500) Warn.confluence_count++; if(Warn.pattern_reversal_warn) Warn.confluence_count++; if(Warn.pattern_rejection_confirm) Warn.confluence_count++; Warn.confluence_3plus = (Warn.confluence_count >= 3); if(Indicators.atr > 0.0) { double dist_ma14 = MathAbs(current - Indicators.ma[1]) / Indicators.atr; Warn.ma14_magnet = (dist_ma14 < 0.7); } for(int i=1; i<6; i++) { if(MathAbs(prev - PriceLevels[i]) < bufPts * 0.5 && MathAbs(current - PriceLevels[i]) > bufPts * 2.0) { Warn.fib_break_confirmed = true; break; } } for(int i=0; i<5; i++) { if(MathAbs(prev - mfib_levels[i]) < bufPts * 0.5 && MathAbs(current - mfib_levels[i]) > bufPts * 2.0) { Warn.mfib_break_confirmed = true; break; } } bool at_strong_ma = (Warn.ma140 || Warn.ma230 || Warn.ma500); if(at_strong_ma) { bool ma140_bounce = Warn.ma140 && ((prev < Indicators.ma[4] && current > Indicators.ma[4]) || (prev > Indicators.ma[4] && current < Indicators.ma[4])); bool ma230_bounce = Warn.ma230 && ((prev < Indicators.ma[5] && current > Indicators.ma[5]) || (prev > Indicators.ma[5] && current < Indicators.ma[5])); bool ma500_bounce = Warn.ma500 && ((prev < Indicators.ma[6] && current > Indicators.ma[6]) || (prev > Indicators.ma[6] && current < Indicators.ma[6])); if((ma140_bounce || ma230_bounce || ma500_bounce) && (Warn.stoch_level_cross || Warn.stoch_reject)) Warn.strong_ma_bounce = true; } Warn.trend_resumption = (IsBull() && BullMA50Reclaim()) || (IsBear() && BearMA50Reclaim()); } void DetectPraiseSignals() { if(!Use_Praise_System) { PraiseSignals.count = 0; return; } double current = Mid(), bufPts = (double)MA_Touch_Buffer; ZeroMemory(PraiseSignals); if(Indicators.atr > 0.0) { double d7 = MathAbs(current - Indicators.ma[0]) / Indicators.atr; double d14 = MathAbs(current - Indicators.ma[1]) / Indicators.atr; double d21 = MathAbs(current - Indicators.ma[2]) / Indicators.atr; bool all_close = (d7 < 0.5) && (d14 < 0.7) && (d21 < 0.9); bool trending = (Indicators.ma[0] > Indicators.ma_prev[0] && Indicators.ma[1] > Indicators.ma_prev[1] && Indicators.ma[2] > Indicators.ma_prev[2]) || (Indicators.ma[0] < Indicators.ma_prev[0] && Indicators.ma[1] < Indicators.ma_prev[1] && Indicators.ma[2] < Indicators.ma_prev[2]); if(all_close && trending && !Warn.band_snap) PraiseSignals.triple_magnet = true; } if(Indicators.atr > 0.0) { double dist = MathAbs(Indicators.ma[1] - Indicators.ma[2]) / Indicators.atr; bool close = (dist < 0.3); bool same_dir = (Indicators.ma[1] > Indicators.ma_prev[1] && Indicators.ma[2] > Indicators.ma_prev[2]) || (Indicators.ma[1] < Indicators.ma_prev[1] && Indicators.ma[2] < Indicators.ma_prev[2]); bool side = (IsBull() && Indicators.ma[0] > Indicators.ma[1]) || (IsBear() && Indicators.ma[0] < Indicators.ma[1]); bool hugging = MathAbs(current - Indicators.ma[1]) / Indicators.atr < 0.8 || MathAbs(current - Indicators.ma[2]) / Indicators.atr < 0.8; if(close && same_dir && side && hugging) PraiseSignals.power_couple = true; } bool stack_bull = (Indicators.ma[0] > Indicators.ma[1]) && (Indicators.ma[1] > Indicators.ma[2]) && (Indicators.ma[2] > Indicators.ma[3]) && (Indicators.ma[3] > Indicators.ma[4]); bool stack_bear = (Indicators.ma[0] < Indicators.ma[1]) && (Indicators.ma[1] < Indicators.ma[2]) && (Indicators.ma[2] < Indicators.ma[3]) && (Indicators.ma[3] < Indicators.ma[4]); bool properly_spaced = true; if(Indicators.atr > 0.0) { for(int i=0; i<4; i++) { double spacing = MathAbs(Indicators.ma[i] - Indicators.ma[i+1]) / Indicators.atr; if(spacing < 0.1) { properly_spaced = false; break; } } } bool all_trending = true; for(int i=0; i<5; i++) if(MathAbs(Indicators.ma[i] - Indicators.ma_prev[i]) / _Point < 5) { all_trending = false; break; } if((stack_bull || stack_bear) && properly_spaced && all_trending) PraiseSignals.ma_stack = true; if(Warn.mfib_break_confirmed && Indicators.adx > 25) PraiseSignals.mfib_breakout = true; if(Warn.fib_break_confirmed && Indicators.adx > 25) PraiseSignals.multi_breakout = true; // PATTERN-ENHANCED PRAISE if(Pattern_Boost_Praise && Use_Pattern_Detection) { // Bullish patterns align with bullish structure if(IsBull() && Patterns.strong_bullish_pattern && (PraiseSignals.ma_stack || PraiseSignals.triple_magnet || PraiseSignals.power_couple)) { PraiseSignals.pattern_confirmation = true; } // Bearish patterns align with bearish structure if(IsBear() && Patterns.strong_bearish_pattern && (PraiseSignals.ma_stack || PraiseSignals.triple_magnet || PraiseSignals.power_couple)) { PraiseSignals.pattern_confirmation = true; } // Multiple bullish patterns with trend momentum if(IsBull() && Patterns.bullish_count >= 2 && Indicators.adx > 25 && !Warn.band_snap) { PraiseSignals.pattern_momentum_align = true; } // Multiple bearish patterns with trend momentum if(IsBear() && Patterns.bearish_count >= 2 && Indicators.adx > 25 && !Warn.band_snap) { PraiseSignals.pattern_momentum_align = true; } } PraiseSignals.count = 0; if(PraiseSignals.triple_magnet) PraiseSignals.count++; if(PraiseSignals.power_couple) PraiseSignals.count++; if(PraiseSignals.mfib_staircase) PraiseSignals.count++; if(PraiseSignals.mfib_express) PraiseSignals.count++; if(PraiseSignals.mfib_breakout) PraiseSignals.count++; if(PraiseSignals.ma_stack) PraiseSignals.count++; if(PraiseSignals.clean_reclaim) PraiseSignals.count++; if(PraiseSignals.multi_breakout) PraiseSignals.count++; if(PraiseSignals.pattern_confirmation) PraiseSignals.count++; if(PraiseSignals.pattern_momentum_align) PraiseSignals.count++; } void DetectFamilyBiasStrength(MODE_FAMILY &family, TREND_BIAS &bias, TREND_STRENGTH &strength) { double current = Mid(); bool mas_bull = (Indicators.ma[0] > Indicators.ma[1]) && (Indicators.ma[1] > Indicators.ma[2]) && (Indicators.ma[2] > Indicators.ma[3]); bool mas_bear = (Indicators.ma[0] < Indicators.ma[1]) && (Indicators.ma[1] < Indicators.ma[2]) && (Indicators.ma[2] < Indicators.ma[3]); double recent_high = iHigh(_Symbol, PERIOD_CURRENT, 0), 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(Indicators.atr > 0.0) ma_clustered = ((MathAbs(Indicators.ma[0] - Indicators.ma[3]) / Indicators.atr) < Chop_ATR_Threshold); bool is_choppy = (ma_clustered || Indicators.adx < 15); if(mas_bull && (MFIB_Bias == BIAS_BULL || !Use_MFIB_382_Bias)) bias = BIAS_BULL; else if(mas_bear && (MFIB_Bias == BIAS_BEAR || !Use_MFIB_382_Bias)) bias = BIAS_BEAR; else if(MFIB_Bias == BIAS_BULL && Indicators.ma[0] > Indicators.ma[3]) bias = BIAS_BULL; else if(MFIB_Bias == BIAS_BEAR && Indicators.ma[0] < Indicators.ma[3]) bias = BIAS_BEAR; else if(Indicators.ma[0] > Indicators.ma[3]) bias = BIAS_BULL; else if(Indicators.ma[0] < Indicators.ma[3]) bias = BIAS_BEAR; else bias = BIAS_NEUTRAL; if(is_choppy && !(mas_bull || mas_bear)) family = FAMILY_CHOP; else if(is_ranging && !(mas_bull || mas_bear)) family = FAMILY_RANGING; else if(bias != BIAS_NEUTRAL) family = FAMILY_TRENDING; else family = FAMILY_TRANSITIONAL; if(Indicators.adx > 25 && (mas_bull || mas_bear)) strength = STRENGTH_STRONG; else if(Indicators.adx > 18 && (mas_bull || mas_bear)) strength = STRENGTH_CONFIRMED; else strength = STRENGTH_WEAK; } PRICE_STATE DetermineState() { if(Current_Family == FAMILY_RANGING) { double current = Mid(), bufPts = (double)MA_Touch_Buffer; bool near_low = Near(current, PriceLevels[1], bufPts) || Near(current, PriceLevels[0], bufPts); bool near_high = Near(current, PriceLevels[5], bufPts) || Near(current, PriceLevels[6], bufPts); if(near_low || near_high) return STATE_RANGE_EDGE_TEST; if(Warn.stoch_reject || Warn.stoch_extreme || Warn.fib_reject || Warn.mfib_reject) return STATE_RANGE_REJECTION; return STATE_RANGE_MID_DRIFT; } if(Current_Family == FAMILY_CHOP) { if(Indicators.adx < 12 && !Warn.stoch_reject) return STATE_CHOP_NOISE; if(Warn.stoch_reject) return STATE_CHOP_FAKEOUT_LOOP; return STATE_CHOP_NOISE; } bool ma7_above_50 = (Indicators.ma[0] > Indicators.ma[3]); bool ma7_below_50 = (Indicators.ma[0] < Indicators.ma[3]); bool ma14_above_50 = (Indicators.ma[1] > Indicators.ma[3]); bool ma14_below_50 = (Indicators.ma[1] < Indicators.ma[3]); bool pullback_sig = (Warn.pullback || Warn.mfib_reject || Warn.fib_reject || Warn.stoch_reject || Warn.band_snap || Warn.stoch_level_cross); bool retrace_sig = (Warn.ma7_cross_21 || Warn.retracement || Warn.ma140 || Warn.ma230 || Warn.ma500); bool strong_ma_pressure = (Warn.ma140 || Warn.ma230 || Warn.ma500 || Warn.ma50); if(IsBull()) { if(ma7_below_50 && !ma14_above_50) return STATE_REVERSAL_CONFIRMED; if(Warn.ma50_break && (retrace_sig || strong_ma_pressure || Warn.stoch_extreme || Warn.confluence_3plus)) return STATE_REVERSAL_ATTEMPT; if(Warn.ma7_cross_21 || strong_ma_pressure || (!Indicators.ma[0] > Indicators.ma[2] && (pullback_sig || retrace_sig))) return STATE_DEEP_RETRACEMENT; if(Warn.ma7_cross_14 || (ma14_above_50 && pullback_sig)) return STATE_PULLBACK; return STATE_CONTINUATION; } if(IsBear()) { if(ma7_above_50 && !ma14_below_50) return STATE_REVERSAL_CONFIRMED; if(Warn.ma50_break && (retrace_sig || strong_ma_pressure || Warn.stoch_extreme || Warn.confluence_3plus)) return STATE_REVERSAL_ATTEMPT; if(Warn.ma7_cross_21 || strong_ma_pressure || (!Indicators.ma[0] < Indicators.ma[2] && (pullback_sig || retrace_sig))) return STATE_DEEP_RETRACEMENT; if(Warn.ma7_cross_14 || (ma14_below_50 && pullback_sig)) return STATE_PULLBACK; return STATE_CONTINUATION; } return STATE_UNKNOWN; } string StateStr(PRICE_STATE s) { if(s == STATE_CONTINUATION) return "CONT"; if(s == STATE_PULLBACK) return "PULLBACK"; if(s == STATE_DEEP_RETRACEMENT) return "RETRACE"; if(s == STATE_REVERSAL_CONFIRMED) return "REV-CONF"; if(s == STATE_RANGE_EDGE_TEST) return "RANGE-EDGE"; if(s == STATE_CHOP_NOISE) return "CHOP"; return "UNKNOWN"; } string BiasStr(TREND_BIAS b) { return (b == BIAS_BULL ? "BULL" : (b == BIAS_BEAR ? "BEAR" : "NEUTRAL")); } string FamilyStr(MODE_FAMILY f) { return (f == FAMILY_TRENDING ? "TREND" : (f == FAMILY_RANGING ? "RANGE" : (f == FAMILY_CHOP ? "CHOP" : "TRANS"))); } void UpdateLabels() { 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, 20); string mode_text = FamilyStr(Current_Family) + " | " + BiasStr(Current_Bias) + " | " + StateStr(Current_State); mode_text += " | P:" + IntegerToString(PraiseSignals.count) + " W:" + IntegerToString(Warn.confluence_count); // Add pattern info if(Use_Pattern_Detection) { mode_text += " | Bull:" + IntegerToString(Patterns.bullish_count) + " Bear:" + IntegerToString(Patterns.bearish_count); } color txt_color = clrWhite; if(Current_Family == FAMILY_TRENDING && IsBull()) txt_color = clrLime; else if(Current_Family == FAMILY_TRENDING && IsBear()) txt_color = clrRed; else if(Current_Family == FAMILY_RANGING) txt_color = clrCyan; else if(Current_Family == FAMILY_CHOP) txt_color = clrViolet; ObjectSetString(0, "StateLabel", OBJPROP_TEXT, mode_text); ObjectSetInteger(0, "StateLabel", OBJPROP_COLOR, txt_color); ObjectSetInteger(0, "StateLabel", OBJPROP_FONTSIZE, 11); } void UpdateModeAndState() { MODE_FAMILY detected_family; TREND_BIAS detected_bias; TREND_STRENGTH detected_strength; DetectFamilyBiasStrength(detected_family, detected_bias, detected_strength); Current_Family = detected_family; Current_Bias = detected_bias; Current_Strength = detected_strength; Current_State = DetermineState(); UpdateLabels(); } void MarkRunners() { double current = Mid(); for(int i=0; i OpenPositions[i].distance_from_current) { PositionRecord tmp = OpenPositions[i]; OpenPositions[i] = OpenPositions[j]; OpenPositions[j] = tmp; } } } for(int i=0; i=0; i--) { if(!PositionGetTicket(i)) 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 = (is_buy && IsBear()) || (!is_buy && IsBull()); if(should_close) { if(Trade.PositionClose(ticket)) ClosedByReversal++; } } } bool IsDirectionAllowed(bool is_buy) { if(!Use_Market_Mode_Filter) return true; if(Current_Family == FAMILY_TRENDING) { if(Current_State == STATE_REVERSAL_CONFIRMED) { if(IsBull() && !is_buy) return false; if(IsBear() && is_buy) return false; return true; } if(Current_State == STATE_PULLBACK || Current_State == STATE_DEEP_RETRACEMENT) { if(IsBull()) return (!is_buy && !BullMA50Reclaim()) || (is_buy && BullMA50Reclaim()); if(IsBear()) return (is_buy && !BearMA50Reclaim()) || (!is_buy && BearMA50Reclaim()); } if(Current_State == STATE_CONTINUATION) { if(IsBull() && !is_buy) return false; if(IsBear() && is_buy) return false; } } return true; } int CountSetupTrades(int setup) { int count = 0; for(int i=0; i= 4) lot = lot * Praise_Multiplier_Supreme; else if(PraiseSignals.count == 3) lot = lot * Praise_Multiplier_Strong; if(Reduce_Continuation_Warn && Warn.confluence_count >= 3) lot = lot * 0.5; } else if(category == CATEGORY_COUNTER_TREND) { if(Pause_Counter_On_Praise && PraiseSignals.count >= 3) lot = lot * 0.25; } } double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN); double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX); double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP); lot = MathMax(lot, minLot); lot = MathMin(lot, maxLot); lot = NormalizeDouble(lot / step, 0) * step; return lot; } void OpenTrade(bool buy, double price, string setup_name, int setup_type, int category) { if(!IsDirectionAllowed(buy)) return; if(!Allow_Re_Entry || (TimeCurrent() - LastEntryTime[setup_type] >= 1)) { if(CountSetupTrades(setup_type) >= Max_Trades_Per_Setup) return; if(PositionsTotal() >= Max_Total_Trades) return; double lot = GetLotSize(category); if(lot < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)) return; SignalParams p = GetSignalParams(category); double sl = buy ? price - p.sl_points * _Point : price + p.sl_points * _Point; double tp = buy ? price + p.tp_points * _Point : price - p.tp_points * _Point; string comment = setup_name + "|" + (category == CATEGORY_COUNTER_TREND ? "CTR" : "CONT"); bool result = buy ? Trade.Buy(lot, _Symbol, 0, sl, tp, comment) : Trade.Sell(lot, _Symbol, 0, sl, tp, comment); if(result) { LastEntryTime[setup_type] = TimeCurrent(); 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].setup_type = setup_type; OpenPositions[size].category = category; OpenPositions[size].setup_name = setup_name; OpenPositions[size].entry_family = Current_Family; OpenPositions[size].entry_bias = Current_Bias; OpenPositions[size].entry_strength = Current_Strength; } } } void ManagePositions() { for(int i=PositionsTotal()-1; i>=0; i--) { ulong ticket = PositionGetTicket(i); if(!ticket) continue; if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue; if(PositionGetInteger(POSITION_MAGIC) != MagicNumber) continue; int idx = -1; for(int j=0; j= 4) trail = Praise_Tight_Trail; if(!OpenPositions[idx].partial_tp_hit && profit_points >= p.partial_tp) { double current_lot = PositionGetDouble(POSITION_VOLUME); double close_size = NormalizeDouble(OpenPositions[idx].original_lot * p.partial_pct / 100.0, 2); if(close_size > 0 && close_size <= current_lot) { if(Trade.PositionClosePartial(ticket, close_size)) OpenPositions[idx].partial_tp_hit = true; } } if(Use_MFIB_Partials && profit_points >= MFIB_Partial_Min_Profit && OpenPositions[idx].mfib_partials_taken < 4) { double mfib_levels[5] = {MFIB.level_236, MFIB.level_382, MFIB.level_050, MFIB.level_618, MFIB.level_786}; bool at_mfib = false; double mfib_price = 0; for(int m=0; m<5; m++) { if(MathAbs(current - mfib_levels[m]) / _Point <= 50) { if((Warn.mfib_reject || Warn.stoch_reject || Warn.stoch_extreme || Warn.confluence_3plus) && (OpenPositions[idx].last_mfib_partial_price == 0 || MathAbs(current - OpenPositions[idx].last_mfib_partial_price) / _Point > 100)) { at_mfib = true; mfib_price = mfib_levels[m]; break; } } } if(at_mfib) { double current_lot = PositionGetDouble(POSITION_VOLUME); double close_size = NormalizeDouble(OpenPositions[idx].original_lot * MFIB_Partial_Percent / 100.0, 2); if(close_size > current_lot) close_size = current_lot * 0.25; if(close_size > 0 && close_size >= SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)) { if(Trade.PositionClosePartial(ticket, close_size)) { OpenPositions[idx].mfib_partials_taken++; OpenPositions[idx].last_mfib_partial_price = mfib_price; } } } } if(!OpenPositions[idx].be_set && profit_points >= p.be_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 >= p.be_points + 50) { OpenPositions[idx].trailing_active = true; double newSL = is_buy ? current - trail * _Point : current + trail * _Point; bool should_modify = is_buy ? (newSL > current_sl + 30 * _Point) : (newSL < current_sl - 30 * _Point); if(should_modify) Trade.PositionModify(ticket, newSL, current_tp); } OpenPositions[idx].close_price = current; } for(int i=ArraySize(OpenPositions)-1; i>=0; i--) { if(!PositionSelectByTicket(OpenPositions[i].ticket)) { double entry = OpenPositions[i].entry; double close_price = OpenPositions[i].close_price; bool is_buy = OpenPositions[i].is_buy; bool at_be = (MathAbs(close_price - entry) / _Point < 10); bool at_sl = !at_be && ((is_buy && close_price < entry) || (!is_buy && close_price > entry)); RecordClosure(OpenPositions[i].setup_type, OpenPositions[i].category, OpenPositions[i].is_buy, close_price, at_sl, at_be); for(int j=i; j= 100) { CalculateLevels(); if(Show_Levels) DrawLevels(); tick_count = 0; } UpdateModeAndState(); ManagePositions(); double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double current = (bid + ask) / 2.0; double buffer = MA_Touch_Buffer * _Point; if(Current_Family == FAMILY_TRENDING && Current_State == STATE_CONTINUATION) { if(IsBull()) { if(Indicators.ma[0] > Indicators.ma[1]) OpenTrade(true, ask, "MA-CROSS↑", SETUP_MA14_CROSS, CATEGORY_CONTINUATION); if(Near(current, Indicators.ma[3], buffer)) OpenTrade(true, ask, "MA50-BOUNCE↑", SETUP_MA50_BOUNCE, CATEGORY_CONTINUATION); if(Near(current, Indicators.ma[4], buffer)) OpenTrade(true, ask, "MA140-BOUNCE↑", SETUP_MA140_BOUNCE, CATEGORY_CONTINUATION); if(Near(current, Indicators.ma[5], buffer)) OpenTrade(true, ask, "MA230-BOUNCE↑", SETUP_MA230_BOUNCE, CATEGORY_CONTINUATION); bool stack = (Indicators.ma[0] > Indicators.ma[1]) && (Indicators.ma[1] > Indicators.ma[2]) && (Indicators.ma[2] > Indicators.ma[3]) && (Indicators.ma[3] > Indicators.ma[4]); if(stack && Indicators.adx > 25 && !Warn.band_snap) OpenTrade(true, ask, "STAIRCASE↑", SETUP_STAIRCASE_ADV, CATEGORY_CONTINUATION); } else if(IsBear()) { if(Indicators.ma[0] < Indicators.ma[1]) OpenTrade(false, bid, "MA-CROSS↓", SETUP_MA14_CROSS, CATEGORY_CONTINUATION); if(Near(current, Indicators.ma[3], buffer)) OpenTrade(false, bid, "MA50-BOUNCE↓", SETUP_MA50_BOUNCE, CATEGORY_CONTINUATION); if(Near(current, Indicators.ma[4], buffer)) OpenTrade(false, bid, "MA140-BOUNCE↓", SETUP_MA140_BOUNCE, CATEGORY_CONTINUATION); bool stack = (Indicators.ma[0] < Indicators.ma[1]) && (Indicators.ma[1] < Indicators.ma[2]) && (Indicators.ma[2] < Indicators.ma[3]) && (Indicators.ma[3] < Indicators.ma[4]); if(stack && Indicators.adx > 25 && !Warn.band_snap) OpenTrade(false, bid, "STAIRCASE↓", SETUP_STAIRCASE_ADV, CATEGORY_CONTINUATION); } } if(Current_Family == FAMILY_RANGING) { if(Near(current, PriceLevels[1], buffer) && Indicators.stoch_k < 35) OpenTrade(true, ask, "RANGE-BUY", SETUP_RANGE_ENGINE, CATEGORY_COUNTER_TREND); if(Near(current, PriceLevels[5], buffer) && Indicators.stoch_k > 65) OpenTrade(false, bid, "RANGE-SELL", SETUP_RANGE_ENGINE, CATEGORY_COUNTER_TREND); } if(Current_Family == FAMILY_CHOP) { if(Warn.stoch_extreme || Warn.stoch_reject || Warn.confluence_3plus) { if(Indicators.stoch_k <= Stoch_Low) OpenTrade(true, ask, "CHOP-REV-BUY", SETUP_MEAN_REV, CATEGORY_COUNTER_TREND); if(Indicators.stoch_k >= Stoch_High) OpenTrade(false, bid, "CHOP-REV-SELL", SETUP_MEAN_REV, CATEGORY_COUNTER_TREND); } } } //+------------------------------------------------------------------+