Viewing the resource: Fade the Break Support & Resistance Expert Advisor in MQL5

Fade the Break Support & Resistance Expert Advisor in MQL5

Allan Munene Mutiiria 2025-06-21 18:23:08 117 Views
Join us for a detailed, professional, and engaging journey through our MQL5 code that automates fore...

Introduction

Greetings, forex navigators! Picture the forex market as a sprawling galaxy, with prices orbiting around key support and resistance levels like planets in a cosmic dance. The Fade the Break S and R EA is your advanced navigation radar, an MQL5 bot that identifies these levels by analyzing recent highs and lows, draws them as red resistance and blue support lines, and fades false breakouts with automated trades. When prices reject resistance or bounce off support, it triggers 10-lot trades with a 100-pip take profit (no stop loss), like plotting a course to capitalize on reversals. This article is your navigator’s log, guiding you through the code with crystal-clear detail for beginners, a flow smoother than a hyperspace jump, and examples—like trading EURUSD reversals—to keep you engaged. We’ll quote variables (e.g., "pricesHighest") and functions (e.g., "OnInit()") for clarity, balancing pro insights with a sprinkle of charm. Ready to fade those cosmic breaks? Let’s launch this trader!

Strategy Blueprint

The Fade the Break EA automates mean-reversion trades:

  • Level Detection: Identifies support and resistance by matching highs/lows within a 10-pip tolerance across visible bars, storing two levels each.

  • Trade Execution: Sells at resistance rejections (bearish candle after breaking above) or buys at support bounces (bullish candle after dipping below), using 10 lots and a 100-pip take profit, no stop loss.

  • Visualization: Draws red resistance and blue support lines with arrows and price labels, validated against current highs/lows.

  • Features: Processes new bars, with robust error handling and level validation to avoid redundant trades. It’s like a cosmic radar, guiding trades by fading false breakouts at market boundaries with precision.

Code Implementation

Let’s navigate the MQL5 code like starship pilots scanning the galaxy, building our trading EA step by step. We’ll flow from setting up the radar to detecting levels, executing trades, and cleaning up, with transitions as seamless as a galactic voyage. Each section includes code blocks, detailed explanations of what we’re doing, and examples to keep you engaged, all while staying beginner-friendly and professional.

Step 1: Setting Up the Cosmic Radar—Initializing the EA

We start by assembling our radar system, configuring arrays for price data and trade setup.

//+------------------------------------------------------------------+
//|                                       FADE THE BREAK S AND R.mq5 |
//|      Copyright 2024, ALLAN MUNENE MUTIIRIA. #@Forex Algo-Trader. |
//|                           https://youtube.com/@ForexAlgo-Trader? |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, ALLAN MUNENE MUTIIRIA. #@Forex Algo-Trader"
#property link      "https://youtube.com/@ForexAlgo-Trader?"
#property description "======= IMPORTANT =======\n"
#property description "1. This is a FREE EA."
#property description "2. To get the source code of the EA, follow the Copyright link."
#property description "3. Incase of anything, contact developer via the link provided."
#property description "Hope you will enjoy the EA Logic.\n"
#property description "*** HAPPY TRADING! ***"
#property version   "1.00"

#include <Trade/Trade.mqh>
CTrade obj_Trade;

double pricesHighest[], pricesLowest[];
double resistanceLevels[2], supportLevels[2];

#define resLine "RESISTANCE LEVEL"
#define colorRes clrRed
#define resLine_Prefix "R"
#define supLine "SUPPORT LEVEL"
#define colorSup clrBlue
#define supLine_Prefix "S"

int OnInit(){
   ArraySetAsSeries(pricesHighest, true);
   ArraySetAsSeries(pricesLowest, true);
   ArrayResize(pricesHighest, 50);
   ArrayResize(pricesLowest, 50);
   return(INIT_SUCCEEDED);
}

We set up our radar with a #property header, updated to your preferred metadata for 2024 with a YouTube link, like powering up our navigation console. We include "Trade/Trade.mqh" for trading via "obj_Trade", define arrays "pricesHighest[]" and "pricesLowest[]" for price data, and "resistanceLevels[2]", "supportLevels[2]" to store levels. Constants ("resLine", "colorRes", etc.) name visual objects. In "OnInit()", we configure arrays as time series with "ArraySetAsSeries()", resize them to 50 elements with "ArrayResize()", and return INIT_SUCCEEDED, signaling, “Radar online, ready to scan!” This primes the EA for level detection, like aligning sensors for a galactic mission.

Step 2: Scanning the Starfield—Detecting Support and Resistance

We scan visible bars to identify support and resistance levels, like mapping cosmic boundaries.

void OnTick(){
   int currBars = iBars(_Symbol,_Period);
   static int prevBars = currBars;
   if (prevBars == currBars) return;
   prevBars = currBars;
   
   int visibleBars = (int)ChartGetInteger(0,CHART_VISIBLE_BARS);
   bool stop_processing = false;
   bool matchFound_high1 = false, matchFound_low1 = false;
   bool matchFound_high2 = false, matchFound_low2 = false;
   
   ArrayFree(pricesHighest);
   ArrayFree(pricesLowest);
   
   int copiedBarsHighs = CopyHigh(_Symbol,_Period,1,visibleBars,pricesHighest);
   int copiedBarsLows = CopyLow(_Symbol,_Period,1,visibleBars,pricesLowest);
   
   ArraySort(pricesHighest);
   ArraySort(pricesLowest);
   ArrayRemove(pricesHighest,10,WHOLE_ARRAY);
   ArrayRemove(pricesLowest,0,visibleBars-10);
   
   for (int i=1; i<=visibleBars-1 && !stop_processing; i++){
      double open = iOpen(_Symbol,_Period,i);
      double high = iHigh(_Symbol,_Period,i);
      double low = iLow(_Symbol,_Period,i);
      double close = iClose(_Symbol,_Period,i);
      datetime time = iTime(_Symbol,_Period,i);
      
      int diff_i_j = 10;
      for (int j=i+diff_i_j; j<=visibleBars-1; j++){
         double open_j = iOpen(_Symbol,_Period,j);
         double high_j = iHigh(_Symbol,_Period,j);
         double low_j = iLow(_Symbol,_Period,j);
         double close_j = iClose(_Symbol,_Period,j);
         datetime time_j = iTime(_Symbol,_Period,j);
         
         double high_diff = NormalizeDouble(MathAbs(high-high_j)/_Point,0);
         bool is_resistance = high_diff <= 10;
         double low_diff = NormalizeDouble(MathAbs(low-low_j)/_Point,0);
         bool is_support = low_diff <= 10;
         
         if (is_resistance){
            for (int k=0; k<ArraySize(pricesHighest); k++){
               if (pricesHighest[k]==high) matchFound_high1 = true;
               if (pricesHighest[k]==high_j) matchFound_high2 = true;
               if (matchFound_high1 && matchFound_high2){
                  if (resistanceLevels[0]==high || resistanceLevels[1]==high_j){
                     Print("CONFIRMED BUT this is the same resistance level, skip updating!");
                     stop_processing = true;
                     break;
                  }
                  else {
                     Print("++++++++= RESISTANCE LEVELS CONFIRMED @ BARS ",i,
                     "(",high,") & ",j,"(",high_j,")");
                     resistanceLevels[0] = high;
                     resistanceLevels[1] = high_j;
                     ArrayPrint(resistanceLevels);
                     draw_S_R_level(resLine,high,colorRes,5);
                     draw_S_R_level_Point(resLine_Prefix,high,time,218,-1,colorRes,90);
                     draw_S_R_level_Point(resLine_Prefix,high,time_j,218,-1,colorRes,90);
                     stop_processing = true;
                     break;
                  }
               }
            }
         }
         if (is_support){
            for (int k=0; k<ArraySize(pricesLowest); k++){
               if (pricesLowest[k]==low) matchFound_low1 = true;
               if (pricesLowest[k]==low_j) matchFound_low2 = true;
               if (matchFound_low1 && matchFound_low2){
                  if (supportLevels[0]==low || supportLevels[1]==low_j){
                     Print("CONFIRMED BUT this is the same support level, skip updating!");
                     stop_processing = true;
                     break;
                  }
                  else {
                     Print("++++++++= SUPPORT LEVELS CONFIRMED @ BARS ",i,
                     "(",low,") & ",j,"(",low_j,")");
                     supportLevels[0] = low;
                     supportLevels[1] = low_j;
                     ArrayPrint(supportLevels);
                     draw_S_R_level(supLine,low,colorSup,5);
                     draw_S_R_level_Point(supLine_Prefix,low,time,217,1,colorSup,-90);
                     draw_S_R_level_Point(supLine_Prefix,low,time_j,217,1,colorSup,-90);
                     stop_processing = true;
                     break;
                  }
               }
            }
         }
         if (stop_processing) break;
      }
      if (stop_processing) break;
   }
}
void draw_S_R_level(string levelName,double price,color clr,int width){
   if (ObjectFind(0,levelName) < 0){
      ObjectCreate(0,levelName,OBJ_HLINE,0,TimeCurrent(),price);
      ObjectSetInteger(0,levelName,OBJPROP_COLOR,clr);
      ObjectSetInteger(0,levelName,OBJPROP_WIDTH,width);
   }
   else {
      ObjectSetDouble(0,levelName,OBJPROP_PRICE,price);
   }
   ChartRedraw(0);
}
void draw_S_R_level_Point(string objName,double price,datetime time,
   int arrowcode,int direction,color clr,double angle){
   string dynamic_name = objName;
   StringConcatenate(objName,objName," @ \nTime: ",time,"\nPrice: ",DoubleToString(price,_Digits));
   if (ObjectCreate(0,objName,OBJ_ARROW,0,time,price)){
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrowcode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      ObjectSetInteger(0,objName,OBJPROP_FONTSIZE,10);
      if (direction > 0) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if (direction < 0) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
   }
   string prefix = (dynamic_name == supLine_Prefix) ? "S" : "R";
   string text = "\n"+prefix +"("+ DoubleToString(price,_Digits)+")";
   string objNameDescr = objName + text;
   if (ObjectCreate(0,objNameDescr,OBJ_TEXT,0,time,price)){
      ObjectSetInteger(0,objNameDescr,OBJPROP_COLOR,clr);
      ObjectSetInteger(0,objNameDescr,OBJPROP_FONTSIZE,10);
      ObjectSetDouble(0,objNameDescr,OBJPROP_ANGLE,angle);
      ObjectSetString(0,objNameDescr,OBJPROP_TEXT,"   "+text);
      if (direction > 0) ObjectSetInteger(0,objNameDescr,OBJPROP_ANCHOR,ANCHOR_LEFT);
      if (direction < 0) ObjectSetInteger(0,objNameDescr,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
   }
   ChartRedraw(0);
}

In "OnTick()", we check for new bars with "iBars()", "prevBars", "currBars", ensuring processing only on new candles, like scanning at regular intervals. We get visible bars with "ChartGetInteger(CHART_VISIBLE_BARS)", load highs and lows with "CopyHigh()", "CopyLow()", and store them in "pricesHighest", "pricesLowest". We sort arrays with "ArraySort()", keeping the top 10 highs ("ArrayRemove(pricesHighest,10,WHOLE_ARRAY)") and bottom 10 lows ("ArrayRemove(pricesLowest,0,visibleBars-10)") for efficiency. We loop through bars, comparing highs/lows within a 10-pip tolerance ("MathAbs()", "_Point") at least 10 bars apart ("diff_i_j"), checking if they match "pricesHighest"/"pricesLowest". Confirmed levels update "resistanceLevels"/"supportLevels", drawn with "draw_S_R_level()" (horizontal lines) and "draw_S_R_level_Point()" (arrows, labels) using "ObjectCreate()", "ObjectSetInteger()", "ObjectSetDouble()", "StringConcatenate()", "DoubleToString()". For example, a resistance at 1.2050 on EURUSD is drawn as a red line with arrows, like mapping a cosmic barrier.

Step 3: Plotting the Course—Validating and Trading Levels

We validate drawn levels and execute fade trades, like launching a starship on a confirmed reversal.

void OnTick(){
   // ... (level detection)
   if (ObjectFind(0,resLine) >= 0){
      double objPrice = ObjectGetDouble(0,resLine,OBJPROP_PRICE);
      double visibleHighs[];
      ArraySetAsSeries(visibleHighs, true);
      CopyHigh(_Symbol,_Period,1,visibleBars,visibleHighs);
      bool matchHighFound = false;
      for (int i=0; i<ArraySize(visibleHighs); i++){
         if (visibleHighs[i]==objPrice){
            Print("> Match price for resistance found @ bar # ",i+1,"(",objPrice,")");
            matchHighFound = true;
            break;
         }
      }
      if (!matchHighFound){
         Print("(",objPrice,")> Match price for the resistance line not found. Delete!");
         deleteLevel(resLine);
      }
   }
   if (ObjectFind(0,supLine) >= 0){
      double objPrice = ObjectGetDouble(0,supLine,OBJPROP_PRICE);
      double visibleLows[];
      ArraySetAsSeries(visibleLows, true);
      CopyLow(_Symbol,_Period,1,visibleBars,visibleLows);
      bool matchLowFound = false;
      for (int i=0; i<ArraySize(visibleLows); i++){
         if (visibleLows[i]==objPrice){
            Print("> Match price for support found @ bar # ",i+1,"(",objPrice,")");
            matchLowFound = true;
            break;
         }
      }
      if (!matchLowFound){
         Print("(",objPrice,")> Match price for the support line not found. Delete!");
         deleteLevel(supLine);
      }
   }
   
   static double resistancePriceTrade = 0;
   if (ObjectFind(0,resLine) >= 0){
      double ResistancePriceLevel = ObjectGetDouble(0,resLine,OBJPROP_PRICE);
      if (resistancePriceTrade != ResistancePriceLevel){
         double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
         double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
         double open1 = iOpen(_Symbol,_Period,1);
         double high1 = iHigh(_Symbol,_Period,1);
         double low1 = iLow(_Symbol,_Period,1);
         double close1 = iClose(_Symbol,_Period,1);
         if (open1 > close1 && open1 < ResistancePriceLevel
            && high1 > ResistancePriceLevel && Bid < ResistancePriceLevel){
            Print("$$$$$$$$$$$$$ SELL NOW SIGNAL!");
            obj_Trade.Sell(10,_Symbol,Bid,0,Bid-100*_Point);
            resistancePriceTrade = ResistancePriceLevel;
         }
      }
   }
   static double supportPriceTrade = 0;
   if (ObjectFind(0,supLine) >= 0){
      double SupportPriceLevel = ObjectGetDouble(0,supLine,OBJPROP_PRICE);
      if (supportPriceTrade != SupportPriceLevel){
         double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
         double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
         double open1 = iOpen(_Symbol,_Period,1);
         double high1 = iHigh(_Symbol,_Period,1);
         double low1 = iLow(_Symbol,_Period,1);
         double close1 = iClose(_Symbol,_Period,1);
         if (open1 < close1 && open1 > SupportPriceLevel
            && low1 < SupportPriceLevel && Ask > SupportPriceLevel){
            Print("$$$$$$$$$$$$$ BUY NOW SIGNAL!");
            obj_Trade.Buy(10,_Symbol,Ask,0,Ask+100*_Point);
            supportPriceTrade = SupportPriceLevel;
         }
      }
   }
}
void deleteLevel(string levelName){
   ObjectDelete(0,levelName);
   ChartRedraw(0);
}

We validate levels with "ObjectFind()", "ObjectGetDouble()", checking if resistance ("resLine") or support ("supLine") prices match current highs/lows via "CopyHigh()", "CopyLow()". If no match, we delete the level with "deleteLevel()", "ObjectDelete()", ensuring relevance, like updating a star map. For trades, we check resistance with "resistancePriceTrade" to avoid duplicates. A sell triggers if the latest bar is bearish ("open1 > close1"), opened below resistance ("open1 < ResistancePriceLevel"), broke above ("high1 > ResistancePriceLevel"), and the bid is below ("Bid < ResistancePriceLevel"), using "obj_Trade.Sell()", 10 lots, no stop loss, and 100-pip take profit ("Bid-100*_Point"). Buys reverse this at support: bullish bar ("open1 < close1"), opened above support ("open1 > SupportPriceLevel"), dipped below ("low1 < SupportPriceLevel"), and ask above ("Ask > SupportPriceLevel"), using "obj_Trade.Buy()". For example, a sell on EURUSD at 1.2045 after rejecting resistance at 1.2050 logs “SELL NOW SIGNAL!” with a take profit at 1.1945, like launching a starship on a reversal course.

Step 4: Docking the Ship—Cleaning Up Resources

When the mission ends, we tidy up to leave the chart clean.

void OnDeinit(const int reason){
}

In "OnDeinit()", we leave it empty, as no cleanup is coded, like leaving radar markers in place. We could add "ObjectsDeleteAll()" to clear "resLine", "supLine", and prefixed objects ("R", "S"), like docking the starship, but for now, it’s a light cleanup, ready for the next voyage.

Why This EA’s a Cosmic Legend (and Keeps You Engaged!)

This EA is a mean-reversion legend, fading breakouts at support and resistance like a radar tracking starship reversals. Its visual lines and automated trades make it powerful, though the 10-lot size and no stop loss require caution (see notes). Example? Fade a false breakout on GBPUSD at 1.3500 resistance, selling for 80 pips to 1.3420, or buy a bounce at 1.3400 support—pure cosmic gold! Beginners can follow, and pros can refine it, making it a must-have for reversal traders.

Putting It All Together

To launch this EA:

  1. Open MetaEditor in MetaTrader 5 like powering up a radar console.

  2. Paste the code, compile (F5), and check for typos—no navigator wants a faulty system.

  3. Drop the EA on your chart, enable AutoTrading, and watch it draw support/resistance lines and open 10-lot trades.

  4. Monitor logs (e.g., “SELL NOW SIGNAL!”) and chart visuals to track trade triggers, like reviewing flight data.

  5. Test on a demo first—real pips deserve a practice voyage!

Conclusion

We’ve crafted a Fade the Break cosmic trader that automates reversal trades at support and resistance, guided by precise level detection and vivid visuals. This MQL5 code is our navigation radar, explained with detail to make you a trading pilot, a touch of charm to keep you engaged, and flow to carry you like a galactic voyage. Ready to fade those breaks? Check our video guide on the website for a front-row seat to this cosmic trading mission. Now go conquer those market boundaries! 🌌

Disclaimer: Trading’s like navigating a galaxy—thrilling but risky. Losses can exceed deposits. Test on a demo account before going live.

Disclaimer: The ideas and strategies presented in this resource are solely those of the author and are intended for informational and educational purposes only. They do not constitute financial advice, and past performance is not indicative of future results. All materials, including but not limited to text, images, files, and any downloadable content, are protected by copyright and intellectual property laws and are the exclusive property of Forex Algo-Trader or its licensors. Reproduction, distribution, modification, or commercial use of these materials without prior written consent from Forex Algo-Trader is strictly prohibited and may result in legal action. Users are advised to exercise extreme caution, perform thorough independent research, and consult with qualified financial professionals before implementing any trading strategies or decisions based on this resource, as trading in financial markets involves significant risk of loss.

Recent Comments

Go to discussion to Comment or View other Comments

No comments yet. Be the first to comment!