//+------------------------------------------------------------------+ //| QuarterTheory_AGGRESSIVE_REENTRY.mq5 | //| Aggressive MA 7 Retest System - Keep Re-entering on Trend | //| 140 MA = Bullish Major | 500 MA = Bearish Major | 10-30 Trades | //+------------------------------------------------------------------+ #property copyright "Aggressive MA Retest System" #property version "14.00" #property strict #include CTrade Trade; //================ INPUT PARAMETERS ==================// input group "=== GENERAL ===" input int MagicNumber = 456789; input double Risk_Per_Trade = 1.0; input int Min_Active_Entries = 10; // Minimum 10 trades input int Max_Simultaneous_Trades = 30; // Maximum 30 trades input group "=== MA TREND SYSTEM ===" input int MA_1 = 7; // PRIMARY - Retest this! input int MA_2 = 14; input int MA_3 = 21; input int MA_4 = 50; input int MA_5 = 140; // BULLISH MAJOR input int MA_6 = 230; input int MA_7 = 500; // BEARISH MAJOR input int MA_8 = 1000; input int MA_9 = 1100; input int MA_10 = 1300; input group "=== RE-ENTRY RULES ===" input bool Reenter_On_MA7_Retest = true; // Re-enter EVERY MA 7 retest input bool Reenter_On_Next_MA = true; // If MA 7 breaks, re-enter at next MA input int MA_Retest_Buffer = 25; // Buffer for MA retest detection input bool Bullish_Major_140 = true; // MA 140 = Bullish major pullback input bool Bearish_Major_500 = true; // MA 500 = Bearish major pullback input group "=== TREND REVERSAL ===" input bool Close_Opposite_On_Reverse = true; // Close all opposite on trend change input bool Reenter_On_New_Trend = true; // Immediate re-entry on new trend input int Min_MA_For_Trend_Change = 3; // MAs needed to confirm reversal input group "=== STOCHASTIC (SECONDARY) ===" input int Stoch_K_Period = 5; input int Stoch_D_Period = 3; input int Stoch_Slowing = 3; input bool Use_Stoch_Filter = false; // Optional - aggressive = off input group "=== TAKE PROFIT & RISK ===" input int Partial_TP_Points = 2300; input double Partial_TP_Percent = 50.0; input int BreakEven_Points = 500; input int Trailing_SL_Points = 500; input int Initial_SL_Points = 800; input group "=== FIBONACCI LEVELS ===" input int Lookback_Bars = 200; input bool Show_Levels = true; input group "=== DAILY LIMITS ===" input double Max_Daily_Loss_Percent = 6.0; input double Max_Daily_Profit_Percent = 40.0; input int Max_Trades_Per_Day = 50; //================ GLOBALS ==================// int Stoch_Handle; double Stoch_K_Current = 0; double PriceLevels[]; string LevelTypes[]; int TotalLevels = 0; int MA_Handles[10]; double MA_Current[10]; double MA_Previous[10]; bool Current_Trend_Bullish = false; bool Current_Trend_Bearish = false; bool Previous_Trend_Bullish = false; bool Previous_Trend_Bearish = false; int MA7_Last_Broken_Index = -1; // Track which MA the MA 7 last broke struct Position { ulong ticket; double entry; double original_lot; bool is_buy; bool partial_tp_hit; bool be_set; datetime entry_time; }; Position OpenPositions[]; double DailyStart = 0; int TodayTrades = 0; datetime LastDay = 0; datetime Last_MA7_Retest_Time = 0; //+------------------------------------------------------------------+ int OnInit() { Print("========================================"); Print("AGGRESSIVE RE-ENTRY v14.0"); Print("MA 7 Retest + Next MA Entry"); Print("140=Bull Major | 500=Bear Major"); Print("========================================"); Trade.SetExpertMagicNumber(MagicNumber); Trade.SetDeviationInPoints(50); Stoch_Handle = iStochastic(_Symbol, PERIOD_CURRENT, Stoch_K_Period, Stoch_D_Period, Stoch_Slowing, MODE_SMA, STO_LOWHIGH); 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); if(MA_Handles[i] == INVALID_HANDLE) { Print("ERROR: MA ", periods[i], " failed"); return INIT_FAILED; } } CalculatePriceLevels(); if(Show_Levels) DrawLevels(); DailyStart = AccountInfoDouble(ACCOUNT_BALANCE); Print("Min/Max Trades: ", Min_Active_Entries, " - ", Max_Simultaneous_Trades); Print("Re-enter on MA 7 retest: ", Reenter_On_MA7_Retest); Print("Bullish major: MA 140 | Bearish major: MA 500"); 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); ObjectsDeleteAll(0, "Level_"); ObjectsDeleteAll(0, "Arrow_"); ObjectsDeleteAll(0, "TrendLabel"); } //+------------------------------------------------------------------+ void CalculatePriceLevels() { ArrayResize(PriceLevels, 0); ArrayResize(LevelTypes, 0); TotalLevels = 0; 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; int size = 0; ArrayResize(PriceLevels, 10); ArrayResize(LevelTypes, 10); PriceLevels[size] = low; LevelTypes[size] = "FIB_0.0"; size++; PriceLevels[size] = low + range * 0.236; LevelTypes[size] = "FIB_0.236"; size++; PriceLevels[size] = low + range * 0.382; LevelTypes[size] = "FIB_0.382"; size++; PriceLevels[size] = low + range * 0.5; LevelTypes[size] = "FIB_0.5"; size++; PriceLevels[size] = low + range * 0.618; LevelTypes[size] = "FIB_0.618"; size++; PriceLevels[size] = low + range * 0.786; LevelTypes[size] = "FIB_0.786"; size++; PriceLevels[size] = high; LevelTypes[size] = "FIB_1.0"; size++; TotalLevels = size; } void DrawLevels() { ObjectsDeleteAll(0, "Level_"); for(int i=0; i 0) MA_Current[i] = curr[0]; if(CopyBuffer(MA_Handles[i], 0, 1, 1, prev) > 0) MA_Previous[i] = prev[0]; } } void UpdateStochastic() { double k_curr[1]; if(CopyBuffer(Stoch_Handle, MAIN_LINE, 0, 1, k_curr) > 0) Stoch_K_Current = k_curr[0]; } //+------------------------------------------------------------------+ //| DETERMINE TREND //+------------------------------------------------------------------+ void DetermineTrend() { UpdateMAs(); // Save previous trend Previous_Trend_Bullish = Current_Trend_Bullish; Previous_Trend_Bearish = Current_Trend_Bearish; int bullish_count = 0; int bearish_count = 0; // Count alignments for(int i=0; i<5; i++) { if(MA_Current[i] > MA_Current[i+1]) bullish_count++; if(MA_Current[i] < MA_Current[i+1]) bearish_count++; } // Determine trend if(bullish_count >= Min_MA_For_Trend_Change && MA_Current[0] > MA_Current[3]) { Current_Trend_Bullish = true; Current_Trend_Bearish = false; } else if(bearish_count >= Min_MA_For_Trend_Change && MA_Current[0] < MA_Current[3]) { Current_Trend_Bullish = false; Current_Trend_Bearish = true; } // Update visual ObjectDelete(0, "TrendLabel"); ObjectCreate(0, "TrendLabel", OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, "TrendLabel", OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, "TrendLabel", OBJPROP_XDISTANCE, 10); ObjectSetInteger(0, "TrendLabel", OBJPROP_YDISTANCE, 30); if(Current_Trend_Bullish) { ObjectSetString(0, "TrendLabel", OBJPROP_TEXT, "TREND: BULLISH ↑ | MA 140 Major"); ObjectSetInteger(0, "TrendLabel", OBJPROP_COLOR, clrLime); } else if(Current_Trend_Bearish) { ObjectSetString(0, "TrendLabel", OBJPROP_TEXT, "TREND: BEARISH ↓ | MA 500 Major"); ObjectSetInteger(0, "TrendLabel", OBJPROP_COLOR, clrRed); } else { ObjectSetString(0, "TrendLabel", OBJPROP_TEXT, "TREND: RANGING"); ObjectSetInteger(0, "TrendLabel", OBJPROP_COLOR, clrYellow); } ObjectSetInteger(0, "TrendLabel", OBJPROP_FONTSIZE, 12); } //+------------------------------------------------------------------+ //| DETECT TREND REVERSAL //+------------------------------------------------------------------+ bool TrendReversed() { // Bullish to Bearish if(Previous_Trend_Bullish && Current_Trend_Bearish) { Print("========================================"); Print("TREND REVERSAL: BULLISH → BEARISH"); Print("========================================"); return true; } // Bearish to Bullish if(Previous_Trend_Bearish && Current_Trend_Bullish) { Print("========================================"); Print("TREND REVERSAL: BEARISH → BULLISH"); Print("========================================"); return true; } return false; } //+------------------------------------------------------------------+ //| CLOSE ALL OPPOSITE TRADES //+------------------------------------------------------------------+ void CloseOppositeTrades(bool close_buys, bool close_sells) { int closed = 0; 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; ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); if(close_buys && type == POSITION_TYPE_BUY) { Trade.PositionClose(ticket); closed++; Print("CLOSED BUY: Trend reversed to BEARISH"); } if(close_sells && type == POSITION_TYPE_SELL) { Trade.PositionClose(ticket); closed++; Print("CLOSED SELL: Trend reversed to BULLISH"); } } if(closed > 0) Print("Total opposite positions closed: ", closed); } //+------------------------------------------------------------------+ //| CHECK IF PRICE RETESTING MA 7 //+------------------------------------------------------------------+ bool IsPriceRetestingMA7(double price) { double buffer = MA_Retest_Buffer * _Point; double ma7 = MA_Current[0]; if(MathAbs(price - ma7) <= buffer) { // Prevent multiple entries on same retest if(TimeCurrent() - Last_MA7_Retest_Time < 60) // 1 minute cooldown return false; Last_MA7_Retest_Time = TimeCurrent(); Print("MA 7 RETEST @ ", ma7, " | Price: ", price); return true; } return false; } //+------------------------------------------------------------------+ //| DETECT MA 7 BREAK & FIND NEXT MA //+------------------------------------------------------------------+ bool MA7_Broke_Through(bool check_bullish, int &next_ma_index) { next_ma_index = -1; // Check if MA 7 broke through any MA for(int i=1; i<7; i++) // Check MAs 14, 21, 50, 140, 230, 500 { if(check_bullish) { // MA 7 broke DOWN through MA if(MA_Previous[0] > MA_Previous[i] && MA_Current[0] <= MA_Current[i]) { next_ma_index = i; MA7_Last_Broken_Index = i; Print("MA 7 BROKE DOWN through MA ", GetMAPeriod(i)); return true; } } else { // MA 7 broke UP through MA if(MA_Previous[0] < MA_Previous[i] && MA_Current[0] >= MA_Current[i]) { next_ma_index = i; MA7_Last_Broken_Index = i; Print("MA 7 BROKE UP through MA ", GetMAPeriod(i)); return true; } } } return false; } //+------------------------------------------------------------------+ //| CHECK IF PRICE AT NEXT MA (after break) //+------------------------------------------------------------------+ bool IsPriceAtNextMA(double price, bool check_bullish, int &ma_idx, string &ma_name) { if(MA7_Last_Broken_Index < 0) return false; double buffer = MA_Retest_Buffer * _Point; // Check the MA that was broken int idx = MA7_Last_Broken_Index; if(MathAbs(price - MA_Current[idx]) <= buffer) { ma_idx = idx; ma_name = "MA " + IntegerToString(GetMAPeriod(idx)); Print("NEXT MA RETEST: ", ma_name, " @ ", MA_Current[idx]); return true; } return false; } //+------------------------------------------------------------------+ //| CHECK IF AT MAJOR MA (140 for bullish, 500 for bearish) //+------------------------------------------------------------------+ bool IsPriceAtMajorMA(double price, bool check_bullish, string &major_name) { double buffer = MA_Retest_Buffer * _Point; if(check_bullish && Bullish_Major_140) { // MA 140 for bullish if(MathAbs(price - MA_Current[4]) <= buffer) { major_name = "MA 140 (BULL MAJOR)"; Print("MAJOR MA TOUCH: ", major_name); return true; } } if(!check_bullish && Bearish_Major_500) { // MA 500 for bearish if(MathAbs(price - MA_Current[6]) <= buffer) { major_name = "MA 500 (BEAR MAJOR)"; Print("MAJOR MA TOUCH: ", major_name); return true; } } return false; } int GetMAPeriod(int index) { int periods[10] = {MA_1, MA_2, MA_3, MA_4, MA_5, MA_6, MA_7, MA_8, MA_9, MA_10}; return periods[index]; } //+------------------------------------------------------------------+ double GetLotSize(int sl_points) { double risk = AccountInfoDouble(ACCOUNT_BALANCE) * Risk_Per_Trade / 100.0; double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE); double lot = risk / ((sl_points * _Point / tickSize) * tickValue); 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; } //+------------------------------------------------------------------+ bool CheckLimits() { MqlDateTime dt; TimeCurrent(dt); dt.hour = 0; dt.min = 0; dt.sec = 0; datetime today = StructToTime(dt); if(today != LastDay) { DailyStart = AccountInfoDouble(ACCOUNT_BALANCE); TodayTrades = 0; LastDay = today; } if(TodayTrades >= Max_Trades_Per_Day) return false; double balance = AccountInfoDouble(ACCOUNT_BALANCE); double pl = ((balance - DailyStart) / DailyStart) * 100.0; if(pl <= -Max_Daily_Loss_Percent || pl >= Max_Daily_Profit_Percent) return false; return true; } //+------------------------------------------------------------------+ void OpenTrade(bool buy, double price, string reason) { double lot = GetLotSize(Initial_SL_Points); if(lot < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)) return; double sl = buy ? price - Initial_SL_Points * _Point : price + Initial_SL_Points * _Point; string comment = (buy ? "BULL" : "BEAR") + " | " + reason; bool result = buy ? Trade.Buy(lot, _Symbol, price, sl, 0, comment) : Trade.Sell(lot, _Symbol, price, sl, 0, comment); if(result) { TodayTrades++; 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].entry_time = TimeCurrent(); Print("========== TRADE ", TodayTrades, " =========="); Print(buy ? "BUY" : "SELL", " @ ", price); Print("Reason: ", reason); Print("==================================="); string arrow_name = "Arrow_" + IntegerToString(ticket); ObjectCreate(0, arrow_name, OBJ_ARROW, 0, TimeCurrent(), price); ObjectSetInteger(0, arrow_name, OBJPROP_COLOR, buy ? clrLime : clrRed); ObjectSetInteger(0, arrow_name, OBJPROP_ARROWCODE, buy ? 233 : 234); ObjectSetInteger(0, arrow_name, OBJPROP_WIDTH, 3); } } //+------------------------------------------------------------------+ 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 lot = PositionGetDouble(POSITION_VOLUME); double close_size = NormalizeDouble(OpenPositions[idx].original_lot * Partial_TP_Percent / 100.0, 2); if(close_size > 0 && close_size <= lot) { Trade.PositionClosePartial(ticket, close_size); OpenPositions[idx].partial_tp_hit = true; } } // Breakeven if(!OpenPositions[idx].be_set && profit_points >= BreakEven_Points) { if((is_buy && sl < entry) || (!is_buy && sl > entry)) { Trade.PositionModify(ticket, entry, 0); OpenPositions[idx].be_set = true; } } // Trailing if(profit_points >= Trailing_SL_Points + 100) { double newSL = is_buy ? current - Trailing_SL_Points * _Point : current + Trailing_SL_Points * _Point; if((is_buy && newSL > sl + 50 * _Point) || (!is_buy && newSL < sl - 50 * _Point)) Trade.PositionModify(ticket, newSL, 0); } } } //+------------------------------------------------------------------+ void OnTick() { static datetime last_trend_check = 0; if(TimeCurrent() - last_trend_check >= 5) { DetermineTrend(); // Check for trend reversal if(TrendReversed() && Close_Opposite_On_Reverse) { if(Current_Trend_Bullish) CloseOppositeTrades(false, true); // Close all sells else if(Current_Trend_Bearish) CloseOppositeTrades(true, false); // Close all buys } last_trend_check = TimeCurrent(); } ManagePositions(); if(!CheckLimits()) return; int buy_count = 0; int sell_count = 0; for(int i=0; i= Max_Simultaneous_Trades) return; bool force_entry = (total < Min_Active_Entries); static datetime last_calc = 0; if(TimeCurrent() - last_calc > 1800) { CalculatePriceLevels(); if(Show_Levels) DrawLevels(); last_calc = TimeCurrent(); } UpdateMAs(); UpdateStochastic(); double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double current = (bid + ask) / 2; // Check re-entry triggers bool ma7_retest = IsPriceRetestingMA7(current); int next_ma_idx = -1; bool ma7_broke_bull = MA7_Broke_Through(true, next_ma_idx); bool ma7_broke_bear = MA7_Broke_Through(false, next_ma_idx); int next_ma_check = -1; string next_ma_name = ""; bool at_next_ma_bull = IsPriceAtNextMA(current, true, next_ma_check, next_ma_name); bool at_next_ma_bear = IsPriceAtNextMA(current, false, next_ma_check, next_ma_name); string major_name = ""; bool at_major_bull = IsPriceAtMajorMA(current, true, major_name); bool at_major_bear = IsPriceAtMajorMA(current, false, major_name); // === BUY ENTRIES (BULLISH TREND ONLY) === if(Current_Trend_Bullish) { bool buy_signal = false; string buy_reason = ""; // 1. MA 7 Retest (PRIMARY!) if(Reenter_On_MA7_Retest && ma7_retest) { buy_signal = true; buy_reason = "MA 7 RETEST"; } // 2. Next MA after MA 7 broke if(Reenter_On_Next_MA && at_next_ma_bull) { buy_signal = true; buy_reason = "NEXT MA: " + next_ma_name; } // 3. Major MA 140 (Bullish major pullback) if(at_major_bull) { buy_signal = true; buy_reason = major_name + " PULLBACK"; } // 4. Force entry if(force_entry && buy_count < Min_Active_Entries / 2) { buy_signal = true; buy_reason = "FORCE (" + IntegerToString(total) + "/" + IntegerToString(Min_Active_Entries) + ")"; } // 5. Immediate re-entry on new trend if(Reenter_On_New_Trend && Previous_Trend_Bearish && buy_count == 0) { buy_signal = true; buy_reason = "NEW BULL TREND"; } if(buy_signal) OpenTrade(true, ask, buy_reason); } // === SELL ENTRIES (BEARISH TREND ONLY) === if(Current_Trend_Bearish) { bool sell_signal = false; string sell_reason = ""; // 1. MA 7 Retest (PRIMARY!) if(Reenter_On_MA7_Retest && ma7_retest) { sell_signal = true; sell_reason = "MA 7 RETEST"; } // 2. Next MA after MA 7 broke if(Reenter_On_Next_MA && at_next_ma_bear) { sell_signal = true; sell_reason = "NEXT MA: " + next_ma_name; } // 3. Major MA 500 (Bearish major pullback) if(at_major_bear) { sell_signal = true; sell_reason = major_name + " PULLBACK"; } // 4. Force entry if(force_entry && sell_count < Min_Active_Entries / 2) { sell_signal = true; sell_reason = "FORCE (" + IntegerToString(total) + "/" + IntegerToString(Min_Active_Entries) + ")"; } // 5. Immediate re-entry on new trend if(Reenter_On_New_Trend && Previous_Trend_Bullish && sell_count == 0) { sell_signal = true; sell_reason = "NEW BEAR TREND"; } if(sell_signal) OpenTrade(false, bid, sell_reason); } } //+------------------------------------------------------------------+