preview
How to Detect Round-Number Liquidity in MQL5

How to Detect Round-Number Liquidity in MQL5

MetaTrader 5Trading |
327 0
Mostafa Ghanbari
Mostafa Ghanbari

Table of Contents


Introduction: The Geometry of Institutional Liquidity

Price often clusters and reverses at whole integers (psychological round-number levels). In practice, this creates operational issues. Some timeframes become cluttered with trivial lines, while on others, strong levels are indistinguishable from noise. Simple modulo tests also fail due to floating‑point artifacts and heterogeneous quote formats (Digits, TickSize) across FX, metals, indices, and crypto. 

This article presents a practical, testable solution for MQL5 that addresses these real-world pain points. We formalize a quality criterion for “correct detection” across instruments and timeframes. We introduce the ZeroSize metric as a numeric measure of level strength. We also describe a deterministic detection pipeline (tick-size normalization plus string-suffix analysis) that is invariant to IEEE‑754 artifacts and symbol formatting. Finally, we provide visualization rules to reduce chart clutter. We also include setup and risk-management guidance so the output can be used in indicators, alerts, and semi-automated systems.

AUDUSD Monthly chart showing RoundLevel Pro hierarchy and precise reversals.

Figure 1: AUDUSD MN1 chart demonstrating precise price reversals at major round number levels (ZeroSize 4-5)



Theoretical Framework: The Psychology of Clustering at Zeros

To understand why these levels work, we must analyze the market microstructure and the order book (Level 2). Round numbers represent "liquidity magnets." Institutional order books utilize limit orders that favor standardized digits for efficiency. Central bank interventions are often defined by whole figures. Algorithmic trading systems cluster their take-profit and stop-loss targets near these milestones. By visualizing this invisible grid of institutional interest, traders can better align their strategies with the "smart money."

Timeframe Hierarchy and Level Significance

While round levels exist on every timeframe, their authority is derived from higher-period charts. A level identified on a monthly chart (as seen in Figure 1) carries significantly more "institutional memory" than a level on a 1-minute chart. When a monthly round level aligns with a daily or H4 level, we encounter a "confluence zone." In these zones, the probability of a high-volume reversal is at its peak because both swing traders and position traders are looking at the same price point.

GBPUSD Monthly chart showing RoundLevel Pro hierarchy and precise reversals.

Figure 2: Visual differentiation of level strength using ZeroSize labels on the GBPUSD MN1 chart

The Correlation Between Timeframes and ZeroSize

A crucial principle in round-number analysis is the scaling of significance across different timeframes. While a ZeroSize 2 level (e.g., 1.1020) might offer a valid scalping opportunity on a 5-minute chart, it often becomes 'market noise' on a daily or weekly chart.

As the timeframe increases, the liquidity requirements for a price reversal also increase. Institutional participants and high-frequency algorithms focus on macro-round numbers (ZeroSize 3 and 4) to execute large-scale orders. Therefore, to maintain high-probability setups, the 'Minimum ZeroSize' filter should be adjusted according to the chart period:

  • Scalping (M1-M15): A minimum ZeroSize of 2 is often sufficient.
  • Day Trading (M30-H4): A minimum ZeroSize of 3 is recommended to filter out minor fluctuations.
  • Swing/Position Trading (daily+): Focus primarily on ZeroSize of 4 (Major Psych Levels) for significant trend reversals.
Trading Style
Timeframes
Recommended Min ZeroSize
Scalping
M1 - M15
2 (e.g., 1.1020)
Intraday
M30 - H4
3 (e.g., 1.1000)
Swing/Investing
Daily/Weekly
4+ (e.g., 1.0000)


The Custom Algorithm: Beyond Simple Modulo Math

A basic mathematical modulo operation (price % step == 0) can tell you if a number is round, but not how round it is relative to others. To overcome this limitation, I developed an innovative string-parsing logic.

Why String Conversion?

Floating-point math in MQL5 can sometimes lead to precision errors (e.g., 1.1000 might be stored as 1.100000000001). Converting the price to a string treats the price as a unique "label," allowing the algorithm to analyze its suffix directly, exactly as a human trader sees it on their screen. This approach provides a reliable and precise mathematical quantification of level strength.

BTCUSD Weekly chart showing RoundLevel Pro hierarchy and precise reversals.

Figure 3: Institutional-level price reactions on BTCUSD at major round levels (ZeroSize 4-5)


Technical Implementation: The Core MQL5 Logic

The centerpiece of this indicator is the GetZeroCount function. It iterates backward through the price string, counting how many consecutive trailing zeros are present. This value directly correlates to the level's psychological and institutional significance.

The Computational Advantage of String Analysis

Standard mathematical approaches often use the % (modulo) operator. However, in MQL5, floating-point arithmetic can be non-deterministic due to IEEE-754 standards. For instance, a price of 1.2000 might be represented internally as 1.19999999999. A modulo operation on this value would fail to identify it as a round number. Using DoubleToString() and StringSubstr(), the indicator analyzes the price as rendered in the terminal UI, reducing false negatives in level detection.

Visualization and User Experience (UX)

To reduce chart clutter, the indicator uses dynamic scaling.Major levels (ZeroSize 4) are rendered with higher Z-order and thicker lines so they remain visible when zoomed out. Minor levels are automatically dimmed or converted to dashed lines to ensure that the trader's focus remains on the most critical liquidity pools. This hierarchical visualization is essential for maintaining "trading flow" and reducing cognitive load during high-volatility sessions.

Why String Parsing Beats Modulo Arithmetic

In MQL5, floating-point precision can be tricky. When you perform a calculation like MathMod(price, 0.01), the result might not be exactly zero due to the way computers store decimals. This leads to missed levels. By converting the price to a string first (DoubleToString). We essentially "freeze" the price as a label. Analyzing the string suffix allows the algorithm to ensure consistent detection of displayed trailing zeros, exactly as the trader sees them on the screen. This is a "What You See Is What You Get" (WYSIWYG) approach to technical analysis.

Algorithm Logic (Step-by-Step):

  1. Normalization: Align the raw price with SYMBOL_TRADE_TICK_SIZE to ensure we are analyzing the actual tradable price.
  2. String Conversion: Transform the double value into a string using DoubleToString to bypass IEEE-754 floating-point inaccuracies.
  3. Digit Extraction: Remove the decimal separator to treat the price as a continuous sequence of integers.
  4. Trailing Analysis: Iterate from the last character backward to count consecutive zeros (the ZeroSize metric).
  5. Filtering: Apply the minZero threshold to determine if the level should be rendered on the chart.

    Inputs:

    input int      InpMinZeroCount = 3;         // Minimum Zeros (Strength) input color    InpMajorColor   = clrRed;    // Major Level Color input color    InpMinorColor   = clrGray;   // Minor Level Color

    Draw level:

    void CreateRoundLevel(string name, double price, int strength)   {    if(ObjectFind(0, name) < 0)      {       ObjectCreate(0, name, OBJ_HLINE, 0, 0, price);       ObjectSetInteger(0, name, OBJPROP_COLOR, (strength >= 4) ? InpMajorColor : InpMinorColor);       ObjectSetInteger(0, name, OBJPROP_WIDTH, (strength >= 4) ? 2 : 1);       ObjectSetString(0, name, OBJPROP_TEXT, "ZeroSize: " + (string)strength);      }   }

    For getting the highest and lowest price:

    // Example of limiting the range to avoid CPU overhead double topPrice = ChartGetDouble(0, CHART_PRICE_MAX); double bottomPrice = ChartGetDouble(0, CHART_PRICE_MIN); //logic to loop between these two prices only

    Main function:

    //+------------------------------------------------------------------+ //| GetZeroCount: Analyzes price to determine institutional strength | //+------------------------------------------------------------------+ int GetZeroCount(double price)   { // 1. Align the price with the symbol's tick size to handle precision artifacts    double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);    if(tickSize > 0)       price = MathRound(price / tickSize) * tickSize; // 2. Convert to string with the symbol's specific digits    string priceStr = DoubleToString(price, _Digits); // 3. Remove decimal point to analyze the sequence of digits    StringReplace(priceStr, ".", "");    StringReplace(priceStr, ",", "");    int zeroCount = 0;    int len = StringLen(priceStr); // 4. Count trailing zeros from right to left    for(int i = len - 1; i >= 0; i--)      {       if(StringSubstr(priceStr, i, 1) == "0")          zeroCount++;       else          break;      }    return zeroCount;   }

    OnCalculate part:

    //+------------------------------------------------------------------+ //| Custom indicator iteration function                              | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total,                 const int prev_calculated,                 const datetime &time[],                 const double &open[],                 const double &high[],                 const double &low[],                 const double &close[],                 const long &tick_volume[],                 const long &volume[],                 const int &spread[])   { //--- For educational purposes, we check only the last known price    double currentPrice = iClose(_Symbol, _Period, 0);    int rank = GetZeroCount(currentPrice);    if(rank >= InpMinZeroCount)      {       //--- Drawing the level on the chart       CreateRoundLevel("Level_" + (string)currentPrice, currentPrice, rank);       Print("Price is near an institutional level of strength: ", rank);      }    return(rates_total);   }

    Example Outputs for GetZeroCount:

    • GetZeroCount(1.10000) -> returns 4
    • GetZeroCount(1.10500) -> returns 2
    • GetZeroCount(70000) -> returns 4

    The resulting strength integer is used dynamically to apply visualization rules in the MetaTrader 5 chart environment.

    ZeroSize 4+: Rendered as thick, solid lines (institutional major).

    ZeroSize 3: Rendered as medium-thickness lines (bank-level liquidity).

    ZeroSize 2: Rendered as thin or dashed lines (day-trading congestion zones).

    Indicator Configuration and Parameters: To provide maximum flexibility for different trading styles, the round level indicator includes several customizable parameters. The table below details the input variables available in the MetaTrader 5 version.

    Parameter
    Type
    Description
    InpMinZeroCount
    int
    Minimum ZeroSize to display (0-5)
    InpMajorColor
    color
    Major Level Color
    InpMinorColor
    color
    Minor Level Color


    Case Studies: Universal Application Across Assets

    A truly robust algorithm should demonstrate consistency across various asset classes, confirming the universal nature of psychological pricing.

    Sensitivity in Gold

    Gold is inherently sensitive to round numbers. Notice in Figure 4 how the market forms major macro peaks or troughs precisely on the round-level lines (e.g., 2000.00 or 2500.00), often forming perfect wick rejections that signal strong institutional supply or demand at these exact points.

    XAUUSD Weekly chart showing RoundLevel Pro hierarchy and precise reversals.

    Figure 4: Gold sensitivity to round levels (ZeroSize 2 and 3)

    Forex Pairs and Minor Crosses

    As seen in previous images (Figures 1-3), major and minor forex pairs consistently respect these zones, validating the applicability of the round level indicator for all currency traders.

    Handling Edge Cases: From Gold to Bitcoin

    One of the primary challenges in round-number detection is the diversity of asset pricing. A robust algorithm must handle different Digits and TickSize configurations seamlessly:

    • High-Value Assets (Bitcoin/Indices): For an asset like BTCUSD trading at 70,000, trailing zeros occur to the left of the decimal point. Our string-parsing logic treats the entire price string as a sequence, correctly identifying 70,000 as a ZeroSize 4 level.

    • Precious Metals & JPY Pairs: Symbols with 2 or 3 digits (like GOLD or USDJPY) are handled by the DoubleToString(price, _Digits) function. This ensures that a level like 150.00 is identified with a strength of 2, which is psychologically equivalent to a ZeroSize 4 level on a 5-digit forex pair (e.g., 1.1000).

    • Floating-Point Artifacts: By normalizing the price to the SYMBOL_TRADE_TICK_SIZE before conversion, we eliminate IEEE-754 precision errors (where 1.2000 might be stored as 1.19999...), ensuring that the indicator sees exactly what the trader sees on the terminal UI.


    Developing a Trading Strategy: Confluence is Key

    The round level indicator is not just a visual aid; it is a complete decision-making framework. While it provides high-probability locations, it does not provide timing. For a complete strategy, we must combine these price zones with momentum overextension metrics, using indicators like the RSI or Stochastic Oscillator (bound oscillators).

    The Momentum Fade Strategy

    This strategy aims to catch trend reversals by identifying moments when momentum becomes "saturated" (oversold or overbought) precisely as price intersects a major institutional round level (ZeroSize 3+).

    Professional Tips for Round Level Trading

    • The Buffer Zone: Do not place orders exactly on the line. Institutions often create a "buffer zone" of 5-10 pips around a major level to trap early entries.

    • News Events: During high-impact news (like NFP), round levels often act as the final destination for "stop hunts" before the real move begins.

    • Currency Specifics: On JPY pairs (3 digits), a ZeroSize of 2 is equivalent in strength to a ZeroSize of 4 on 5-digit pairs. The indicator automatically adjusts for these symbol-specific differences.

    XAUUSD M1 chart showing RoundLevel Pro hierarchy and precise reversals.

    Figure 5: Price rejection at major round level on gold, ideal for a momentum fade strategy

    As demonstrated in this chart of Gold M1, the price approached the ZeroSize 3 level during a high-volatility session and reacted with a perfect pin-bar rejection, confirming our theory.

    Execution Rules:

    1. Identify Zone: Price must be approaching a ZeroSize 3 or 4 level.
    2. Momentum Check: A bound oscillator (e.g., RSI) must be overextended (e.g., >70 during price approach to resistance).
    3. Candlestick Confirmation: Look for wick rejection (pin bar) directly on the line (Figure 5).
    4. Entry:Enter on the close of the confirmation candle.

      Rationale: Extreme momentum plus institutional liquidity at a whole number increases the chance of a fast reversal.


      Frequently Asked Questions (FAQ)

      Q1: Why are round numbers more effective on higher timeframes?

      A: Higher timeframes like daily and monthly reflect the decisions of long-term institutional investors. While a round number on a 1-minute chart might cause a 2-pip bounce, a round number on a monthly chart represents a major structural pivot point that can lead to hundreds of pips of movement.

      Q2: Does the "ZeroSize" logic work for JPY pairs?

      A: Yes. The algorithm is designed to be symbol-agnostic. On JPY pairs (3 digits), a price like 150.00 will be detected as ZeroSize 2, which is psychologically equivalent to a ZeroSize of 4 on 5-digit pairs. The indicator handles these conversions automatically.

      Q3: Can I use round levels for crypto trading?

      A: Absolutely. In fact, Bitcoin (BTCUSD) is extremely sensitive to major round levels like 40,000, 50,000, and 100,000. The string-parsing logic counts the zeros regardless of the asset's price scale.

      Q4: How do I avoid "fakeouts" at these levels?

      A: Never trade the level in isolation. Always look for a "confluence" (as discussed in Section 1). If a round level aligns with a Fibonacci retracement or a previous daily high, the probability of a fakeout is significantly reduced.

      Q5: Is the indicator CPU-intensive?

      A: No. By utilizing a loop that only processes the current price on the current chart, the indicator maintains a near-zero latency, making it suitable for low-spec VPS environments.


      Risk Management and Position Sizing

      Trading near high-liquidity zones requires a disciplined approach to risk. Because institutions often hunt for liquidity just beyond major round numbers, we recommend the following:

      • 10-Pip Buffer: Place your stop-loss at least 10-15 pips away from the ZeroSize 4 levels to allow for potential volatility spikes and potential liquidity hunts often observed around major psychological milestones.
      • Scaling In: Consider entering half your position at the first touch and the other half after a successful retest of the level.
      • Trailing Stops: Once price moves away from a major round level, it often gains momentum. Use a trailing stop to capture the full extension of the institutional move.


      Conclusion: The Blueprint for Professional S/R Trading

      We converted the observation that price reacts to round numbers into a reproducible engineering and trading blueprint. We explained why modulo checks fail and how level significance scales with timeframe. We then introduced ZeroSize as a formal strength based on normalized price and counting trailing zeros in the string representation—to deliver deterministic detection in MQL5. 

      Practical deliverables include:

      • the GetZeroCount function, which reduces floating-point false negatives via SYMBOL_TRADE_TICK_SIZE normalization and DoubleToString;
      • configurable filters (minZero and related inputs) mapped to trading styles and timeframes;
      • visualization rules for major and minor levels;
      • a basic, testable trading framework combining the level, momentum/confirmation, and risk-management rules (buffer, scaling, trailing stops). 

      This package can be integrated into indicators, alert systems or EAs and validated across symbols and Digits/TickSize configurations. Future work will add multi‑symbol scanning and real‑time alerting, but the current implementation already provides a robust, auditable method to detect and trade institutional liquidity clusters without the floating‑point and formatting pitfalls of naive approaches.

      For further study and community interaction:

      • Source Code (MQL5): The core implementation logic is provided as an attached file (RoundLevel_Base.mq5) to this article for educational purposes.
      • Future Development: I plan to further enhance this algorithm by integrating multi-symbol scanning and real-time alert systems in future updates.

      Attached files |
      Markov Chain-Based Matrix Forecasting Model Markov Chain-Based Matrix Forecasting Model
      We are going to create a matrix forecasting model based on a Markov chain. What are Markov chains, and how can we use a Markov chain for Forex trading?
      Price Action Analysis Toolkit Development (Part 66): Developing a Structured Head and Shoulders Scanner in MQL5 Price Action Analysis Toolkit Development (Part 66): Developing a Structured Head and Shoulders Scanner in MQL5
      Head and Shoulders patterns are difficult to identify consistently in live market data due to noise and structural ambiguity. This article presents a structured, triangle-based MQL5 indicator that isolates pattern components, constructs the neckline, and validates formations using ATR, symmetry, and slope constraints. The system detects and draws standard and inverse patterns, assigns a quality score, and confirms breakouts with optional alerts, enabling consistent and rule-based chart analysis.
      Creating a Traditional Renko Overlay Indicator in MQL5 Creating a Traditional Renko Overlay Indicator in MQL5
      Create a traditional Renko indicator in MQL5 that converts candlestick closing prices into fixed-size blocks displayed on the main chart. We calculate the movement from the closing price of the last block, create new blocks of a user-defined size, confirm reversals using the two-block rule, manage block closing prices in a dynamic array, and display rectangles for visualizing the trend in real time.
      Building a Trade Analytics System (Part 1): Foundation and System Architecture Building a Trade Analytics System (Part 1): Foundation and System Architecture
      We design a simple external trade analytics pipeline for MetaTrader 5 and implement its backend in Python with Flask and SQLite. The article defines the architecture, data model, and versioned API, and shows how to configure the environment, initialize the database, and run the server locally. As a result, you get a clean base to capture closed-trade records from MetaTrader 5 and store them for later analysis.