Welcome to Forex Algo-Trader

Welcome to the place where trading meets automation. Build your own trading EAs, test wild ideas, learn new strategies, and chat with traders who speak your language. Whether you’re coding your first bot or fine-tuning a master strategy, this is where smart trading comes to life—and sometimes breaks just so we can fix it better.

Dive In Now

Forex Algo-Trader is your premier platform for mastering forex trading. Explore advanced tools, expert resources, and a dynamic community designed to support traders at all levels. From beginners to seasoned professionals, our platform empowers you to succeed in the fast-paced forex market.

Welcome to Forex Trading

Automated Trading with MQL5

Discover the power of automated trading. Here's an advanced MQL5 Expert Advisor example using CRT (Candle Range Theory) for a more sophisticated strategy to get you started.

//+------------------------------------------------------------------+
//| CRT Candle Range Theory EA.mq5 |
//| Copyright 2025, Allan Munene Mutiiria. |
//| https://t.me/Forex_Algo_Trader |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Allan Munene Mutiiria."
#property link "https://t.me/Forex_Algo_Trader"
#property version "1.00"
#include <Trade\Trade.mqh>
//+------------------------------------------------------------------+
//| Enums |
//+------------------------------------------------------------------+
enum SLTP_Method { // Define SL/TP method enum
   Dynamic_Method = 0, // Dynamic based on breach extreme
   Static_Method = 1 // Static based on fixed points
};
enum TrailingTypeEnum { // Define trailing type enum
   Trailing_None = 0, // None
   Trailing_Points = 1 // By Points
};
//+------------------------------------------------------------------+
//| Input Parameters |
//+------------------------------------------------------------------+
input ENUM_TIMEFRAMES RangeTF = PERIOD_H4; // Timeframe for Range Definition
input double TradeVolume = 0.01; // Trade Volume Size
input double RR_Ratio = 1.3; // Risk to Reward Ratio
input SLTP_Method SLTP_Approach = Static_Method; // SL/TP Calculation Method
input int SL_Points = 100; // SL Points (for Static Method)
input TrailingTypeEnum TrailingType = Trailing_None; // Trailing Stop Type
input double Trailing_Stop_Points = 30.0; // Trailing Stop in Points
input double Min_Profit_To_Trail_Points = 50.0; // Min Profit to Start Trailing in Points
input int UniqueID = 123456789; // Unique Trade Identifier
input int MaxPositionsDir = 1; // Max Positions per Direction
input ENUM_TIMEFRAMES ConfirmTF = PERIOD_CURRENT; // Confirmation Timeframe (for bar closures)
input int ConfirmBars = 1; // Bars to Confirm Reversal on Close (0 to disable)
input bool UseManipFilter = true; // Use Manipulation Depth Filter
input double MinManipPct = 5.0; // Min Manipulation % of Range (if filter enabled)
input double DistribProjPct = 50.0; // Distribution Projection % of Range Duration
//+------------------------------------------------------------------+
//| Global Variables |
//+------------------------------------------------------------------+
CTrade obj_Trade; //--- Trade object
datetime prevRangeTime = 0; //--- Previous range time
double rangeMax = 0.0; //--- Range maximum
double rangeMin = 0.0; //--- Range minimum
bool positiveDirection = false; //--- Positive direction flag
bool rangeBreached = false; //--- Range breached flag
double breachPoint = 0.0; //--- Breach point
string maxLevelObj = "RangeMaxLevel"; //--- Max level object name
string minLevelObj = "RangeMinLevel"; //--- Min level object name
string maxTextObj = "CRT_High_Text"; //--- CRT high text object
string minTextObj = "CRT_Low_Text"; //--- CRT low text object
bool tradedSetup = false; //--- Traded setup flag
datetime breachTime = 0; //--- Breach time
datetime lastConfirmTime = 0; //--- Last confirm time
//+------------------------------------------------------------------+
//| EA Start Function |
//+------------------------------------------------------------------+
int OnInit() {
   obj_Trade.SetExpertMagicNumber(UniqueID); //--- Set magic number
   return(INIT_SUCCEEDED); //--- Return success
}
//+------------------------------------------------------------------+
//| EA Stop Function |
//+------------------------------------------------------------------+
void OnDeinit(const int code) {
   ObjectDelete(ChartID(), maxLevelObj); //--- Delete max level
   ObjectDelete(ChartID(), minLevelObj); //--- Delete min level
   ObjectDelete(ChartID(), maxTextObj); //--- Delete max text
   ObjectDelete(ChartID(), minTextObj); //--- Delete min text
   // Clean dynamic rects and texts
   ObjectsDeleteAll(ChartID(), "RangeRectangle_", OBJ_RECTANGLE); //--- Delete range rects
   ObjectsDeleteAll(ChartID(), "ManipRectangle_", OBJ_RECTANGLE); //--- Delete manip rects
   ObjectsDeleteAll(ChartID(), "DistribRectangle_", OBJ_RECTANGLE); //--- Delete distrib rects
   ObjectsDeleteAll(ChartID(), "AccumText_", OBJ_TEXT); //--- Delete accum texts
   ObjectsDeleteAll(ChartID(), "ManipText_", OBJ_TEXT); //--- Delete manip texts
   ObjectsDeleteAll(ChartID(), "DistribText_", OBJ_TEXT); //--- Delete distrib texts
}
//+------------------------------------------------------------------+
//| Tick Processing Function |
//+------------------------------------------------------------------+
void OnTick() {
   double currBid = SymbolInfoDouble(_Symbol, SYMBOL_BID); //--- Get current bid
   double currAsk = SymbolInfoDouble(_Symbol, SYMBOL_ASK); //--- Get current ask
   datetime currRangeTime = iTime(_Symbol, RangeTF, 0); //--- Get current range time
   if (currRangeTime != prevRangeTime) { //--- Check new range
      prevRangeTime = currRangeTime; //--- Update prev time
      double prevMax = iHigh(_Symbol, RangeTF, 1); //--- Get prev high
      double prevMin = iLow(_Symbol, RangeTF, 1); //--- Get prev low
      double prevStart = iOpen(_Symbol, RangeTF, 1); //--- Get prev open
      double prevEnd = iClose(_Symbol, RangeTF, 1); //--- Get prev close
      rangeMax = prevMax; //--- Set range max
      rangeMin = prevMin; //--- Set range min
      positiveDirection = (prevEnd > prevStart); //--- Set direction
      rangeBreached = false; //--- Reset breached
      breachPoint = positiveDirection ? rangeMin : rangeMax; //--- Set breach point
      tradedSetup = false; //--- Reset traded
      breachTime = 0; //--- Reset breach time
      lastConfirmTime = 0; //--- Reset confirm time
      RenderLevel(maxLevelObj, rangeMax, clrOrange, "Range Max"); //--- Render max level
      RenderLevel(minLevelObj, rangeMin, clrPurple, "Range Min"); //--- Render min level
      // Add text labels for current CRT High and Low
      datetime labelTime = currRangeTime; //--- Set label time
      RenderText(maxTextObj, labelTime, rangeMax, "CRT High", clrOrange, ANCHOR_RIGHT_LOWER); //--- Render high text
      RenderText(minTextObj, labelTime, rangeMin, "CRT Low", clrPurple, ANCHOR_RIGHT_UPPER); //--- Render low text
      // Draw background rectangle for the accumulation phase (range candle) with fill true
      string rangeRectObj = "RangeRectangle_" + IntegerToString(currRangeTime); //--- Range rect name
      datetime rangeStartTime = iTime(_Symbol, RangeTF, 1); //--- Get start time
      datetime rangeEndTime = currRangeTime; //--- Set end time
      ObjectCreate(ChartID(), rangeRectObj, OBJ_RECTANGLE, 0, rangeStartTime, rangeMax, rangeEndTime, rangeMin); //--- Create rect
      color rectClr = positiveDirection ? clrLightGreen : clrLightPink; //--- Set rect color
      ObjectSetInteger(ChartID(), rangeRectObj, OBJPROP_COLOR, rectClr); //--- Set color
      ObjectSetInteger(ChartID(), rangeRectObj, OBJPROP_FILL, true); //--- Set fill
      ObjectSetInteger(ChartID(), rangeRectObj, OBJPROP_BACK, true); //--- Set back
      ObjectSetInteger(ChartID(), rangeRectObj, OBJPROP_STYLE, STYLE_SOLID); //--- Set style
      ChartRedraw(ChartID()); //--- Redraw chart
   }
   if (rangeMax == 0.0 || rangeMin == 0.0) return; //--- Return if no range
   bool justBreached = false; //--- Init just breached
   if (positiveDirection && currBid <= rangeMin) { //--- Check positive breach
      if (!rangeBreached) { //--- Check not breached
         rangeBreached = true; //--- Set breached
         justBreached = true; //--- Set just breached
         breachTime = TimeCurrent(); //--- Set breach time
      }
      breachPoint = MathMin(breachPoint, currBid); //--- Update breach point
   } else if (!positiveDirection && currBid >= rangeMax) { //--- Check negative breach
      if (!rangeBreached) { //--- Check not breached
         rangeBreached = true; //--- Set breached
         justBreached = true; //--- Set just breached
         breachTime = TimeCurrent(); //--- Set breach time
      }
      breachPoint = MathMax(breachPoint, currBid); //--- Update breach point
   }
   if (rangeBreached && !tradedSetup) { //--- Check breached and not traded
      // Check for confirmed reversal on bar closures
      bool reversalConfirmed = false; //--- Init confirmed
      if (ConfirmBars == 0) { //--- Check no confirm
         reversalConfirmed = true; //--- Set confirmed
      } else { //--- Else
         datetime currConfirmTime = iTime(_Symbol, ConfirmTF, 0); //--- Get confirm time
         if (currConfirmTime != lastConfirmTime) { //--- Check new confirm
            lastConfirmTime = currConfirmTime; //--- Update last confirm
            int confirmedCount = 0; //--- Init count
            for (int i = 1; i <= ConfirmBars; i++) { //--- Iterate bars
               double confirmClose = iClose(_Symbol, ConfirmTF, i); //--- Get close
               if (positiveDirection && confirmClose > rangeMin) { //--- Check positive
                  confirmedCount++; //--- Increment count
               } else if (!positiveDirection && confirmClose < rangeMax) { //--- Check negative
                  confirmedCount++; //--- Increment count
               }
            }
            if (confirmedCount >= ConfirmBars) { //--- Check confirmed
               reversalConfirmed = true; //--- Set confirmed
            }
         }
      }
      // Calculate manipulation depth for filter
      bool manipSufficient = true; //--- Init sufficient
      double rangeSize = rangeMax - rangeMin; //--- Calc range size
      double manipDepth = positiveDirection ? (rangeMin - breachPoint) : (breachPoint - rangeMax); //--- Calc depth
      double manipPct = (manipDepth / rangeSize) * 100.0; //--- Calc percent
      if (UseManipFilter) { //--- Check filter
         if (manipPct < MinManipPct) { //--- Check insufficient
            manipSufficient = false; //--- Set insufficient
         }
      }
      bool justEntered = false; //--- Init entered
      datetime entryTime = 0; //--- Init entry time
      double entryPrice = 0.0; //--- Init entry price
      double gainTarget = 0.0; //--- Init target
      if (reversalConfirmed && manipSufficient) { //--- Check confirmed and sufficient
         if (positiveDirection && currBid > rangeMin && ActivePositions(POSITION_TYPE_BUY) < MaxPositionsDir) { //--- Check buy entry
            double lossStop; //--- Init SL
            if (SLTP_Approach == Dynamic_Method) { //--- Check dynamic
               lossStop = NormalizeDouble(breachPoint, _Digits); //--- Set SL
               double riskDistance = currAsk - breachPoint; //--- Calc risk
               gainTarget = NormalizeDouble(currAsk + riskDistance * RR_Ratio, _Digits); //--- Set TP
            } else { //--- Static
               lossStop = NormalizeDouble(currAsk - SL_Points * _Point, _Digits); //--- Set SL
               gainTarget = NormalizeDouble(currAsk + SL_Points * RR_Ratio * _Point, _Digits); //--- Set TP
            }
            if (obj_Trade.Buy(TradeVolume, _Symbol, currAsk, lossStop, gainTarget, "CRT Positive Entry")) { //--- Open buy
               if (obj_Trade.ResultRetcode() == TRADE_RETCODE_DONE) { //--- Check success
                  Print("Positive Signal: Range raided below min, reversed back in (confirmed). Entry at ", DoubleToString(currAsk, _Digits),
                        " SL at ", DoubleToString(lossStop, _Digits), " TP at ", DoubleToString(gainTarget, _Digits)); //--- Log entry
                  Print("Debug: Accumulation Range: ", DoubleToString(rangeSize / _Point, 0), " points. Manipulation Depth: ", DoubleToString(manipDepth / _Point, 0), " points (", DoubleToString(manipPct, 2), "% of range)"); //--- Log debug
                  string markerName = "EntryMarker_" + IntegerToString(TimeCurrent()); //--- Marker name
                  ObjectCreate(ChartID(), markerName, OBJ_ARROW, 0, TimeCurrent(), currBid); //--- Create marker
                  ObjectSetInteger(ChartID(), markerName, OBJPROP_ARROWCODE, 233); //--- Set code
                  ObjectSetInteger(ChartID(), markerName, OBJPROP_COLOR, clrBlue); //--- Set color
                  ObjectSetInteger(ChartID(), markerName, OBJPROP_ANCHOR, ANCHOR_BOTTOM); //--- Set anchor
                  tradedSetup = true; //--- Set traded
                  justEntered = true; //--- Set entered
                  entryTime = TimeCurrent(); //--- Set entry time
                  entryPrice = currAsk; //--- Set entry price
               }
            }
         } else if (!positiveDirection && currBid < rangeMax && ActivePositions(POSITION_TYPE_SELL) < MaxPositionsDir) { //--- Check sell entry
            double lossStop; //--- Init SL
            if (SLTP_Approach == Dynamic_Method) { //--- Check dynamic
               lossStop = NormalizeDouble(breachPoint, _Digits); //--- Set SL
               double riskDistance = breachPoint - currBid; //--- Calc risk
               gainTarget = NormalizeDouble(currBid - riskDistance * RR_Ratio, _Digits); //--- Set TP
            } else { //--- Static
               lossStop = NormalizeDouble(currBid + SL_Points * _Point, _Digits); //--- Set SL
               gainTarget = NormalizeDouble(currBid - SL_Points * RR_Ratio * _Point, _Digits); //--- Set TP
            }
            if (obj_Trade.Sell(TradeVolume, _Symbol, currBid, lossStop, gainTarget, "CRT Negative Entry")) { //--- Open sell
               if (obj_Trade.ResultRetcode() == TRADE_RETCODE_DONE) { //--- Check success
                  Print("Negative Signal: Range raided above max, reversed back in (confirmed). Entry at ", DoubleToString(currBid, _Digits),
                        " SL at ", DoubleToString(lossStop, _Digits), " TP at ", DoubleToString(gainTarget, _Digits)); //--- Log entry
                  Print("Debug: Accumulation Range: ", DoubleToString(rangeSize / _Point, 0), " points. Manipulation Depth: ", DoubleToString(manipDepth / _Point, 0), " points (", DoubleToString(manipPct, 2), "% of range)"); //--- Log debug
                  string markerName = "EntryMarker_" + IntegerToString(TimeCurrent()); //--- Marker name
                  ObjectCreate(ChartID(), markerName, OBJ_ARROW, 0, TimeCurrent(), currAsk); //--- Create marker
                  ObjectSetInteger(ChartID(), markerName, OBJPROP_ARROWCODE, 234); //--- Set code
                  ObjectSetInteger(ChartID(), markerName, OBJPROP_COLOR, clrRed); //--- Set color
                  ObjectSetInteger(ChartID(), markerName, OBJPROP_ANCHOR, ANCHOR_TOP); //--- Set anchor
                  tradedSetup = true; //--- Set traded
                  justEntered = true; //--- Set entered
                  entryTime = TimeCurrent(); //--- Set entry time
                  entryPrice = currBid; //--- Set entry price
               }
            }
         }
      }
      // If just entered trade, draw manipulation rectangle, distribution, and labels (including accumulation)
      if (justEntered) { //--- Check entered
         string setupSuffix = IntegerToString(prevRangeTime); //--- Setup suffix
         // Label the range as Accumulation phase (now only for complete setups)
         string accumTextUnique = "AccumText_" + setupSuffix; //--- Accum text name
         double accumPrice = (rangeMax + rangeMin) / 2; //--- Accum price
         datetime labelTime = prevRangeTime; //--- Label time
         RenderText(accumTextUnique, labelTime, accumPrice, "Accumulation", clrBlue, ANCHOR_RIGHT); //--- Render accum text
         // Calculate the manipulation extreme using candle highs/lows between currRangeTime and entryTime
         int startBar = iBarShift(_Symbol, PERIOD_CURRENT, prevRangeTime); //--- Start bar
         int endBar = iBarShift(_Symbol, PERIOD_CURRENT, entryTime); //--- End bar
         if (startBar < 0 || endBar < 0) return; //--- Return invalid
         if (startBar < endBar) { int temp = startBar; startBar = endBar; endBar = temp; } //--- Swap if needed
         int barCount = startBar - endBar + 1; //--- Calc bar count
         double manipExtreme; //--- Init manip extreme
         double manipStartPrice = positiveDirection ? rangeMin : rangeMax; //--- Manip start
         if (positiveDirection) { //--- Check positive
            int lowestBar = iLowest(_Symbol, PERIOD_CURRENT, MODE_LOW, barCount, endBar); //--- Get lowest
            manipExtreme = iLow(_Symbol, PERIOD_CURRENT, lowestBar); //--- Set extreme
         } else { //--- Negative
            int highestBar = iHighest(_Symbol, PERIOD_CURRENT, MODE_HIGH, barCount, endBar); //--- Get highest
            manipExtreme = iHigh(_Symbol, PERIOD_CURRENT, highestBar); //--- Set extreme
         }
         // Draw manipulation rectangle (border only) from CRT end to signal time
         string manipRectObj = "ManipRectangle_" + setupSuffix; //--- Manip rect name
         double topPrice = MathMax(manipStartPrice, manipExtreme); //--- Top price
         double bottomPrice = MathMin(manipStartPrice, manipExtreme); //--- Bottom price
         ObjectCreate(ChartID(), manipRectObj, OBJ_RECTANGLE, 0, prevRangeTime, topPrice, entryTime, bottomPrice); //--- Create rect
         ObjectSetInteger(ChartID(), manipRectObj, OBJPROP_COLOR, clrBlue); //--- Set color
         ObjectSetInteger(ChartID(), manipRectObj, OBJPROP_FILL, false); //--- Set no fill
         ObjectSetInteger(ChartID(), manipRectObj, OBJPROP_BACK, true); //--- Set back
         ObjectSetInteger(ChartID(), manipRectObj, OBJPROP_STYLE, STYLE_DOT); //--- Set style
         ObjectSetInteger(ChartID(), manipRectObj, OBJPROP_WIDTH, 2); //--- Set width
         ChartRedraw(ChartID()); //--- Redraw chart
         // Add manipulation text label at breach time
         string manipTextUnique = "ManipText_" + setupSuffix; //--- Manip text name
         int anchorManip = positiveDirection ? ANCHOR_RIGHT_UPPER : ANCHOR_RIGHT_LOWER; //--- Manip anchor
         RenderText(manipTextUnique, breachTime, manipExtreme, "Manipulation", clrBlue, anchorManip); //--- Render manip text
         // Label and draw distribution
         string distribTextUnique = "DistribText_" + setupSuffix; //--- Distrib text name
         color distribClr = positiveDirection ? clrGreen : clrRed; //--- Distrib color
         int anchor = positiveDirection ? ANCHOR_LEFT_LOWER : ANCHOR_LEFT_UPPER; //--- Distrib anchor
         RenderText(distribTextUnique, entryTime, entryPrice, "Distribution", distribClr, anchor); //--- Render distrib text
         // Draw border rectangle (fill false) for distribution phase (% of range duration)
         string distribRectObj = "DistribRectangle_" + setupSuffix; //--- Distrib rect name
         datetime rangeStartTime = iTime(_Symbol, RangeTF, 1); //--- Range start
         datetime rangeEndTime = prevRangeTime; //--- Range end
         long duration = rangeEndTime - rangeStartTime; //--- Calc duration
         double projFactor = MathMax(DistribProjPct / 100.0, 0.01); //--- Proj factor
         datetime projEndTime = entryTime + (datetime)(duration * projFactor); //--- Proj end
         double topDistrib = MathMax(entryPrice, gainTarget); //--- Top distrib
         double bottomDistrib = MathMin(entryPrice, gainTarget); //--- Bottom distrib
         ObjectCreate(ChartID(), distribRectObj, OBJ_RECTANGLE, 0, entryTime, topDistrib, projEndTime, bottomDistrib); //--- Create rect
         ObjectSetInteger(ChartID(), distribRectObj, OBJPROP_COLOR, distribClr); //--- Set color
         ObjectSetInteger(ChartID(), distribRectObj, OBJPROP_FILL, false); //--- Set no fill
         ObjectSetInteger(ChartID(), distribRectObj, OBJPROP_BACK, true); //--- Set back
         ObjectSetInteger(ChartID(), distribRectObj, OBJPROP_STYLE, STYLE_SOLID); //--- Set style
         ObjectSetInteger(ChartID(), distribRectObj, OBJPROP_WIDTH, 2); //--- Set width
         ChartRedraw(ChartID()); //--- Redraw chart
      }
   }
   if (TrailingType == Trailing_Points && PositionsTotal() > 0) { //--- Check trailing
      ApplyPointsTrailing(); //--- Apply trailing
   }
}
//+------------------------------------------------------------------+
//| Render Horizontal Level |
//+------------------------------------------------------------------+
void RenderLevel(string objName, double levelVal, color levelClr, string levelDesc) {
   ObjectDelete(ChartID(), objName); //--- Delete object
   ObjectCreate(ChartID(), objName, OBJ_HLINE, 0, 0, levelVal); //--- Create hline
   ObjectSetInteger(ChartID(), objName, OBJPROP_COLOR, levelClr); //--- Set color
   ObjectSetInteger(ChartID(), objName, OBJPROP_STYLE, STYLE_DOT); //--- Set style
   ObjectSetString(ChartID(), objName, OBJPROP_TOOLTIP, levelDesc); //--- Set tooltip
   ChartRedraw(ChartID()); //--- Redraw chart
}
//+------------------------------------------------------------------+
//| Render Text Label |
//+------------------------------------------------------------------+
void RenderText(string objName, datetime timeVal, double priceVal, string textStr, color textClr, int anchorVal) {
   ObjectDelete(ChartID(), objName); //--- Delete object
   ObjectCreate(ChartID(), objName, OBJ_TEXT, 0, timeVal, priceVal); //--- Create text
   ObjectSetString(ChartID(), objName, OBJPROP_TEXT, textStr); //--- Set text
   ObjectSetInteger(ChartID(), objName, OBJPROP_COLOR, textClr); //--- Set color
   ObjectSetInteger(ChartID(), objName, OBJPROP_ANCHOR, anchorVal); //--- Set anchor
   ObjectSetInteger(ChartID(), objName, OBJPROP_FONTSIZE, 10); //--- Set fontsize
   ChartRedraw(ChartID()); //--- Redraw chart
}
//+------------------------------------------------------------------+
//| Count Active Positions by Type |
//+------------------------------------------------------------------+
int ActivePositions(ENUM_POSITION_TYPE posType) {
   int total = 0; //--- Init total
   for (int pos = PositionsTotal() - 1; pos >= 0; pos--) { //--- Iterate positions
      if (PositionGetSymbol(pos) == _Symbol && PositionGetInteger(POSITION_MAGIC) == UniqueID && PositionGetInteger(POSITION_TYPE) == posType) { //--- Check position
         total++; //--- Increment total
      }
   }
   return total; //--- Return total
}
//+------------------------------------------------------------------+
//| Apply Points Trailing Stop |
//+------------------------------------------------------------------+
void ApplyPointsTrailing() {
   double point = _Point; //--- Get point
   for (int i = PositionsTotal() - 1; i >= 0; i--) { //--- Iterate positions
      if (PositionGetTicket(i) > 0) { //--- Check ticket
         if (PositionGetString(POSITION_SYMBOL) == _Symbol && PositionGetInteger(POSITION_MAGIC) == UniqueID) { //--- Check symbol magic
            double sl = PositionGetDouble(POSITION_SL); //--- Get SL
            double tp = PositionGetDouble(POSITION_TP); //--- Get TP
            double openPrice = PositionGetDouble(POSITION_PRICE_OPEN); //--- Get open
            ulong ticket = PositionGetInteger(POSITION_TICKET); //--- Get ticket
            if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { //--- Check buy
               double newSL = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID) - Trailing_Stop_Points * point, _Digits); //--- Calc new SL
               if (newSL > sl && SymbolInfoDouble(_Symbol, SYMBOL_BID) - openPrice > Min_Profit_To_Trail_Points * point) { //--- Check conditions
                  obj_Trade.PositionModify(ticket, newSL, tp); //--- Modify position
               }
            } else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { //--- Check sell
               double newSL = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK) + Trailing_Stop_Points * point, _Digits); //--- Calc new SL
               if (newSL < sl && openPrice - SymbolInfoDouble(_Symbol, SYMBOL_ASK) > Min_Profit_To_Trail_Points * point) { //--- Check conditions
                  obj_Trade.PositionModify(ticket, newSL, tp); //--- Modify position
               }
            }
         }
      }
   }
}
//+------------------------------------------------------------------+
                

The Candle Range Theory (CRT) EA is a sophisticated automated trading system designed for MetaTrader 5. It operates on the principle of identifying significant range candles on a higher timeframe and trading the subsequent breach and reversal patterns. The strategy is structured around three key phases:

  • Accumulation Phase: This is the initial range candle where price consolidates, setting the high (CRT High) and low (CRT Low) boundaries. The EA detects this range and draws visual levels on the chart for reference.
  • Manipulation Phase: Following the accumulation, the price breaches one of the range extremes (low in bullish ranges or high in bearish ranges). The EA measures the depth of this manipulation and applies a filter to ensure it meets a minimum percentage threshold of the range size, avoiding false signals.
  • Distribution Phase: Upon reversal back into the range with confirmation from closed bars on a specified timeframe, the EA enters a trade in the direction of the reversal. It projects the distribution phase duration based on a percentage of the accumulation range time and draws visual rectangles for each phase.

The EA supports dynamic or static stop-loss and take-profit calculations, with options for trailing stops by points. It limits maximum positions per direction and uses a unique magic number for trade management. This strategy aims to capture high-probability reversals after liquidity grabs, optimizing for defined risk-reward ratios while providing visual aids for manual oversight.

EA Visual Demo
Learn More About MQL5 Strategies

Market Insights

Stay ahead of the forex market with cutting-edge analysis tools and insights. Discover top-rated algorithms, explore trending strategies, and leverage data-driven solutions to enhance your trading decisions.

Trading Robot Automation

Automated Trading Revolution

Embrace the future of trading with automated bots that execute strategies flawlessly. Say goodbye to endless hours monitoring charts and let intelligent robots handle trades 24/7, optimizing opportunities while you focus on what matters most.


Rating and Popular

Discover the highest rated and most popular tools available on our platform, curated to help you find the best options for your trading needs.

Loading...

Hottest Price Offers

Explore the hottest price offers on premium tools, featuring significant discounts to help you acquire top-quality trading resources at unbeatable prices.

Loading...

Quick Start Guide

Get up and running in no time with these simple steps.

1

Sign Up

Create your free account and join the community.

2

Explore Tools

Browse and download trading algorithms.

3

Join Discussions

Participate in forums and learn from experts.

4

Start Trading

Apply strategies and automate your trades.


Essential Trading Tools

Essential Trading Tools

Equip yourself with a comprehensive suite of trading tools designed to streamline analysis, execution, and risk management. From indicators to backtesting software, these resources are vital for building robust strategies and achieving consistent results in the forex market.

Advanced Trading Platforms

Explore top-tier trading platforms that provide intuitive interfaces, powerful charting capabilities, and seamless integration with automated systems. Whether you're scalping or swing trading, these platforms offer the reliability and features needed to execute your vision effectively.

Trading Platforms

Trading Tools

Empower your trading with our professional suite of tools. From advanced platforms to seamless broker integrations, high-performance VPS solutions, and real-time data feeds, our resources are designed to optimize your trading strategy.

Trading Platforms

Execute trades with precision using platforms like MetaTrader 4, MetaTrader 5, and TradingView, optimized for speed and analytics.

Explore Platforms

Brokers

Partner with trusted brokers offering tight spreads, rapid execution, and regulatory compliance to maximize your potential.

Find Brokers

VPS Providers

Ensure uninterrupted trading with high-performance VPS solutions, optimized for 24/7 algo-trading with minimal latency.

Discover VPS

Data Feeds

Power your strategies with real-time market data from trusted providers, delivering a competitive edge.

Access Data

Automated Trading

Transform your trading with advanced automation. Gain expert insights on developing strategies, managing risks, and leveraging top-tier tools to trade smarter and more efficiently.

How It Works

Learn the mechanics of algo-trading, from coding to execution, and discover how automation drives consistent results.

Learn More

Winning Strategies

Master techniques like scalping, trend-following, and breakout strategies to excel in the markets.

Explore Strategies

Risk Management

Protect your capital with advanced risk controls, ensuring safe trading in volatile conditions.

Manage Risk

Trading Tools

Equip your algorithms with elite platforms, code editors, and backtesting tools for optimal performance.

Get Tools

Our Growing Community

See how Forex Algo-Trader is empowering traders worldwide.

1200+
Users
98+
Tools
11200+
Downloads
2+
Community
263+
Resources

Why Choose Forex Algo-Trader?

Comprehensive Resources

Access guides, tutorials, and articles on forex trading strategies and coding trading robots.

Vibrant Community

Connect with traders worldwide to share ideas, strategies, and experiences in trading and algo development.

Market Tools

Discover and download algorithms, indicators, and tools from our marketplace to enhance your trading knowledge.


Trader Community

Join a global network of forex traders. Engage in discussions, share insights, and learn from peers to refine your skills and stay informed on the latest market trends.


What Traders Say

"Forex Algo-Trader has great resources for learning about algo trading and coding robots."

- John Doe, Aspiring Algo Trader

"The community support is incredible. I've shared and learned so many strategies from fellow traders."

- Jane Smith, Beginner Trader

"Found useful tools and insights in the marketplace that helped me develop better trading ideas."

- Alex Johnson, Experienced Coder


Learning Materials

Comprehensive Learning Materials

Dive into a rich collection of educational resources, including YouTube videos, detailed articles, proven trading strategies, and more. Whether you're a novice or expert, these materials provide the knowledge to refine your skills and stay ahead in algorithmic trading.


Learning Resources

Explore a comprehensive library of forex trading resources, including guides, tutorials, and articles tailored for all skill levels. Enhance your expertise and stay ahead in algorithmic trading.


Ready to Elevate Your Trading?

Join Forex Algo-Trader today and unlock the tools, insights, and community you need to succeed in the forex market.

Sign Up Now

About Us

Forex Algo-Trader is dedicated to empowering traders with innovative tools and a supportive community. Our team of forex and technology experts is committed to redefining trading success.

Our Mission

Empowering traders with innovative solutions for accessible and profitable forex trading.

Our Team

A dedicated group of forex and tech experts focused on your trading success.

Our Vision

Redefining forex trading through collaboration and continuous innovation.


Frequently Asked Questions

What is Forex Algo-Trader?

Forex Algo-Trader is a platform for automated forex trading, offering tools, resources, and a community for traders.

How do I become a seller?

If eligible, click the 'Become a Seller' button in the hero section to apply.

Are the tools free?

Some tools are free, while others are premium with discounts available.

How do I download tools from the marketplace?

Browse the market section, select a tool, and follow the download instructions after purchase or for free tools.

What is algorithmic trading?

Algorithmic trading involves using computer programs to execute trades based on predefined criteria, automating the trading process.

How can I join the community discussions?

Sign up or log in, then navigate to the community section to participate in threads and share your insights.

What resources are available for beginners?

We offer tutorials, guides, and beginner-friendly articles in the resources section to help you get started with forex and algo trading.

How secure is the platform?

We use industry-standard security measures to protect your data and transactions.