Market Activity Measured by Quote Wait Times

Market Activity Measured by Quote Wait Times
Download ALL MT5 indicators (5917)
YouTube Video Thumbnail



Similar MetaTrader Tools

Market Activity Measured by Quote Wait Times

Info

The Market Activity Measured by Quote Wait Times is a Indicator for MetaTrader 5 that overviewevery metatrader 5 chart displays market activity through tick volume, which counts quote updates per bar. However, this metric often fails to directly answer the trader's question: is the market unusually active right now.

Usage

This tool is typically used for enhancing chart analysis and decision making.

Platform

This Indicator works exclusively on MetaTrader 5 (both build 600+ and newer versions).

Setup

Place the downloaded file in MQL5/Indicators folder via File ? Open Data Folder in MetaTrader 5.


How to Install and Use Market Activity Measured by Quote Wait Times

1. Installation: Place your file in the MQL/Indicators folder via "Open Data Folder" and restart your terminal.

2. Loading: Find the indicator in the Navigator, drag it onto your chart, and configure the input parameters in the popup window.

3. Customization: Press Ctrl+I to open the indicator list, select your tool, and click "Properties" to change colors, levels, or visual styles.

4. Updating: Replace the old file in the Indicators folder with the new version and restart the platform to apply changes.

Frequently Asked Questions

Q: Why is my indicator not showing? A: Verify the file is in the MQL/Indicators folder, or try right-clicking the "Indicators" tree in the Navigator and clicking "Refresh."

Q: Do custom indicators slow down the platform? A: Too many complex indicators can impact performance; remove unused ones via the "Indicator List" (Ctrl+I).

Q: Can I use MT4 indicators on MT5? A: No, MQL4 and MQL5 are distinct languages; ensure the indicator is compiled specifically for your platform version.

What this tool does

OverviewEvery MetaTrader 5 chart displays market activity through tick volume, which counts quote updates per bar.

Typical Use Case

This Indicator excels in automated trading and technical analysis on MetaTrader 5.

Compatible Platform & Setup

This Indicator works on MetaTrader 5. Place the file in the MQL5/Indicators folder and restart the terminal.

Description & Settings

Related: Extreme Price Filter: Identify and Avoid Market Traps - another powerful indicator for MetaTrader 5 traders.

Overview

Also recommended: Market Structure BOS and CHoCH Indicator: Swing Points, No Repaint, Alerts - similar indicator with strong performance on MetaTrader 5.

Every MetaTrader 5 chart displays market activity through tick volume, which counts quote updates per bar. However, this metric often fails to directly answer the trader's question: is the market unusually active right now?

Several factors complicate the interpretation of tick volume. Firstly, the time of day significantly influences quote frequency; for instance, EURUSD can see quote waits forty-seven times longer during quiet periods compared to peak hours. Consequently, high tick volume often simply reflects peak trading hours rather than genuine market intensity. Secondly, bar data is only complete upon bar closure, making mid-bar tick counts incomplete and incomparable. Thirdly, the resolution is limited; twenty quotes spread over a minute and twenty quotes in a rapid three-second burst yield the same bar count.

This indicator addresses these issues by focusing on the time between consecutive quotes instead of counts per bar. It normalizes for the typical daily trading rhythm and models the remaining activity using the autoregressive conditional duration (ACD) model developed by Engle and Russell. The output is a single, continuously updated number that indicates market activity relative to the norm for the current hour: a reading of 1 signifies normal activity, 2 indicates activity is twice as fast as usual, and 0.5 means it is half as fast.

From quotes to events: the waits between quote changes, a burst, two ticks in one millisecond folded into one event, and a closed market that starts a new session.

What the gauge measures and does not measure.
This indicator measures market conditions, not price direction, and provides no predictive information on future price movements. In tests across six symbols, its inclusion in a volatility forecast that already used live prices improved the subsequent one-to-five-minute forecast for every symbol, increasing R-squared by a range of 0.1 to 2.5 points. While this improvement is consistent, it is modest. At a one-minute horizon for currency pairs and gold, a simple rhythm-adjusted rolling tick count performed equally well or better.

How It Works

Quotes become events.
On a retail feed, a tick represents a change in the quote, not a trade. Ticks occurring within the same millisecond are consolidated into a single event, as a zero wait signifies a rapid burst of data rather than an extremely short interval. Waits exceeding five minutes (default) are treated as market closures (weekends, daily index breaks, holidays). The next event following such a gap initiates a new session, and the model resets to its long-run level rather than extrapolating from a prolonged absence of quotes.

The daily rhythm is divided out.
A time-of-day profile is established by averaging quote waits within thirty-minute intervals. Each wait is logged according to its start time, the only time known when the forecast is made. The profile is then adjusted by interpolating between bin centers, ensuring smooth transitions at interval boundaries. This profile is scaled so that the adjusted waits average exactly one, which allows a reading of 1 to signify normal activity.

The normal wait between quote changes at each time of day, EURUSD and US30, on a logarithmic scale. This shape repeats every day and carries no information about today.

The remaining clustering is modelled.
Even after accounting for the daily rhythm, periods of high activity tend to be followed by more high activity. The ACD model maintains a single running value, psi, representing the expected adjusted wait until the next quote. This value is updated with each subsequent wait:

psi_i = omega + alpha * x_(i-1) + beta * psi_(i-1)

For those familiar with GARCH(1,1), this recursion will be recognizable, with waits replacing squared returns. The sum of alpha and beta, known as persistence, can be interpreted as a half-life; for EURUSD, a persistence of 0.9975 means a burst's influence halves after approximately 277 events, roughly three minutes at the average quote pace. Omega is set such that the long-run expected wait equals one. Consequently, the gauge reads exactly 1 when psi is at its long-run level.

The expected wait through a burst of quotes: each short wait pulls it down, and afterwards it decays back toward normal, halving the gap every half-life.

Three primary outputs are derived from the live state, each updated in constant time without requiring historical data:

Activity ratio
: This is the main gauge, calculated as the long-run mean divided by psi.

Expected wait
: This is psi, adjusted to include the time-of-day rhythm, expressed in milliseconds for the next quote.

Silence ratio
: This is the time elapsed since the last quote divided by the expected wait. Since psi is only updated when a quote arrives, this ratio indicates, between quotes, when the next quote is overdue.

Reading the Chart

The indicator displays its output in a subwindow. The primary line represents the logarithm, base 2, of the activity ratio. This logarithmic scale ensures that doubling and halving of activity appear as equidistant movements from the normal level (1). The line is colored grey when near normal, orange-red when activity is twice the normal pace or higher, and blue when at half the normal pace or lower, with labeled thresholds. A dotted line shows raw tick volume relative to its average over the rhythm period, also on a logarithmic scale, serving as a visual contrast to highlight what the gauge effectively filters out.

EURUSD M1 through the London open: tick volume increases with the session, while the activity ratio remains near normal because this increase is typical for that hour.

Across the three trading days displayed, the time of day accounts for 72.8% of the variation in the tick volume line but only 29.7% of the variation in the activity line. When quotes suddenly arrive at a much faster rate than usual for the hour, the activity line turns orange-red within seconds, even before the bar has closed and its tick volume count is partial.

A genuine burst: the activity ratio rises into the busy zone within seconds, before the bar has closed.

The indicator does not perform model fitting on the chart itself. Upon loading, it learns the rhythm from the seven trading days preceding the plotted range, warms up the state through these days, and then replays the last three trading days. Therefore, no displayed data has been adjusted by a profile that included its own observation.

Recommended Setup

Setting

Recommended value

Notes

Symbol

EURUSD (shipped parameters)

The default alpha and beta parameters are optimized for EURUSD. Any symbol with a genuine market feed can be used once its specific parameters are fitted, as demonstrated below.

Timeframe

M1 to M15

The gauge is computed per quote. The timeframe primarily influences how frequently a value is written to the plot. Shorter timeframes capture and display bursts of activity as they occur.

Tick history

Ten trading days

The rhythm period and the days to be plotted are read from tick history upon loading. If the terminal has not yet downloaded the required ticks, the indicator will display a message and begin drawing once the data becomes available.

Recalibration

About monthly

And whenever you change the symbol or broker. Recalibration is necessary if the persistence value shows a noticeable change between fits, indicating that the older parameters may be outdated.

For reference, these are the Weibull fits on thirty days of quotes ending 14 September 2026. They reflect one broker's feed; treat them as starting points and refit on your own account.

Symbol

Alpha

Beta

Persistence

Half-life, events

EURUSD

0.0210

0.9765

0.99750

277

GBPUSD

0.0376

0.9586

0.99625

184

USDJPY

0.0443

0.9518

0.99615

180

XAUUSD

0.0357

0.9584

0.99402

116

US30

0.0228

0.9764

0.99920

870

SPX500

0.0200

0.9788

0.99885

604

What the Evidence Shows

Activity is only relevant if it offers insights into future market behavior. The specific question tested was whether knowing the current market activity improves forecasts of volatility over the next one to fifteen minutes. Given that volatility tends to cluster, any metric correlated with recent volatility might appear beneficial. Therefore, all comparisons were made against a baseline forecast that already incorporated recent volatility, with regressions fitted on the first 70% of thirty days of data and scored on the remaining 30%.

At the bar close, activity measures show similar performance.
Incorporating any activity measure alongside recent bar volatility improved the fifteen-minute forecast by three to eight points of R-squared across five out of six symbols. Closed-bar tick volume, a live rolling count, and the ACD gauge performed within approximately one R-squared point of each other, as a completed bar contains the full tick count.

Inside the bar, live measures demonstrate an advantage.
Mid-bar, the ACD gauge outperformed closed-bar tick volume on all six symbols for both five- and one-minute horizons, achieving improvements of 1.0 to 8.8 points in R-squared.

Fresh price data contributes significantly to this gain.
Live realized volatility alone surpassed the ACD gauge alone on every tested symbol. A substantial portion of the benefit from a live activity measure stems from its up-to-date nature.

Activity still adds value beyond price data.
Even when live volatility was already included in the forecast, adding the ACD gauge improved predictions on all six symbols for both tested horizons.

What each activity measure adds to the mid-bar forecast when live volatility is known, for each symbol and horizon.

Symbol

ACD gauge, 5 min

Rolling counts, 5 min

ACD gauge, 1 min

Rolling counts, 1 min

EURUSD

+0.012

+0.005

+0.012

+0.016

GBPUSD

+0.013

+0.010

+0.012

+0.019

USDJPY

+0.003

+0.002

+0.006

+0.011

XAUUSD

+0.015

+0.021

+0.014

+0.023

US30

+0.022

+0.015

+0.019

+0.015

SPX500

+0.024

+0.008

+0.019

+0.011

The improvements in test R-squared are generally small: a fraction of a point for USDJPY, one to one and a half points for other currency pairs and gold, and around two points for indices. The ACD gauge showed its strongest performance at the five-minute horizon and for indices. At the one-minute horizon for currencies and gold, rhythm-adjusted rolling counts performed equally well or better. The advantage of the ACD gauge over a simple count is that it does not require the selection of a counting window, and its memory is determined by the data itself rather than being manually set.

Input Parameters

Parameter

Default

Description

InpAlpha

0.020987

This parameter represents the weight assigned to the most recent quote wait. The default value is derived from the EURUSD fit.

InpBeta

0.976518

This parameter determines the weight applied to the previous expectation. Both alpha and beta must be non-negative, and their sum must be less than one; otherwise, the indicator will reject the inputs.

InpGapSec

300

Any wait longer than this duration, in seconds, is considered a market closure. The corresponding bar will be left blank, and the model will restart from its normal state.

InpRhythmDays

7

The number of trading days prior to the plotted range used for learning the time-of-day profile and initializing the model's state.

InpBinMinutes

30

The duration of each time-of-day bin in minutes. This value must divide the day evenly.

InpPlotDays

3

The number of trading days to be plotted, including the current day.

InpBusy

2.0

The activity ratio threshold at or above which the indicator line is colored busy. This value must be greater than 1.

InpQuiet

0.5

The activity ratio threshold at or below which the indicator line is colored quiet. This value must be between 0 and 1.

InpShowVolume

true

This option controls whether to display raw tick volume against its average as a dotted contrast line.

Reading the Gauge from an Expert Advisor

The buffer layout is standardized in AcdTypes.mqh using ENUM_ACD_BUFFER, allowing EAs to reliably access data via iCustom:

Buffer

Contents

0, ACD_BUF_ACTIVITY

The logarithm base 2 of the activity ratio, which is the primary plotted line.

1, ACD_BUF_COLOR

A color index representing the state: 0 for normal, 1 for busy, and 2 for quiet.

2, ACD_BUF_VOLUME

The logarithm base 2 of tick volume relative to its average.

3, ACD_BUF_RATIO

The raw activity ratio itself. This is the buffer typically read by an EA.

4, ACD_BUF_EXPECTED

For forming bars only: the expected wait time in milliseconds until the next quote.

#include


//--- the input groups take a slot each: "" passes the first one

int
h=iCustom(_Symbol,PERIOD_M1,"ACD\ACD_Activity","",0.020987,0.976518);

double
r[1];
if(CopyBuffer(h,ACD_BUF_RATIO,1,1,r)==1 && r[0]!=EMPTY_VALUE && r[0]>=2.0)
Print("the last closed bar ended at twice the normal pace or more");

A ready-made silence ratio is not published because timer events are not delivered to an indicator created through iCustom. Consequently, a value refreshed between quotes would not reach the EA. However, an EA can compute it by recording GetTickCount64 on each new tick and then, within its own timer function, dividing the elapsed milliseconds by buffer 4 (ExpectedWaitMs). A result significantly above 1 indicates that the next quote is overdue.

A practical application is in trade execution rather than prediction: delaying a new order when the market is moving at several times its normal pace, as spreads and slippage are often at their worst during such periods. Spreads were not measured in the aforementioned tests; therefore, this aspect should be tested independently on your own account.

Fitting Your Own Symbol

Fitting the model for a specific symbol requires approximately thirty days of quotes and takes several tens of seconds. Since the indicator runs on the chart's thread, the fitting process is handled separately by a script. The library facilitates this entire process with a few function calls. CAcdEvents loads tick data day by day to build the event series, and CAcdModel calibrates the rhythm and recursion parameters using the first 70% of the events and then evaluates them on the remaining data:

#include


void
OnStart()
{
//--- thirty days of quotes on this symbol
CAcdEvents ev;
const datetime to=TimeCurrent();
if(!ev.Load(_Symbol,to-30*86400,to))
return;

//--- rhythm and recursion fitted on the first 70%, scored on the rest
CAcdModel model;
SAcFit fit;
if(!model.SetEvents(ev) || !model.Calibrate(ACD_DIST_WEIBULL,fit))
return;
PrintFormat("alpha %.6f beta %.6f clustering gain on the test range %+.3f",
fit.params.alpha,fit.params.beta,fit.ll_test-fit.base_ll_test);
}
Paste the printed alpha and beta values into the indicator's input parameters. The clustering gain indicates the improvement in log-likelihood per event over a baseline model that considers only the rhythm without any clustering; this value should be positive on the held-out range, confirming that the identified clustering is statistically significant for the symbol. The Weibull shape parameter, also reported by the fit, is not required for live operation as it influences the likelihood calculation but not the expected wait time.

The live state management is also handled by a class. CAcdState utilizes the fitted parameters and the time-of-day profile. Once initialized, each incoming quote requires only a constant-time update. This allows an EA to implement the gauge functionality directly, without relying on the indicator:

#include


CAcdState state;

//--- initialization: provide the fitted parameters and the rhythm profile
state.Init(fit.params,model.Diurnal(),300);

//--- process each new tick
if(state.OnEvent((long)tick.time_msc))
PrintFormat("activity %.2f, next quote expected in %.0f ms",
state.ActivityRatio(),state.ExpectedWaitMs());
The time-of-day profile can also be generated independently using CAcdDiurnal. This class allows for setup, fitting of waits, and normalization of average waits across any specified range of events, similar to how the indicator operates.

Limitations

These results are based on quotes from a single broker and do not reflect actual trades. Quote data may be influenced by the broker's aggregation and filtering mechanisms, in addition to genuine market activity. Consequently, parameters fitted on one broker's feed may not be directly transferable to another.

Some data feeds may not represent true market behavior. On the author's account, BTCUSD quotes arrived at fixed intervals, with most waits being close to a quarter of a second. Prior to fitting, it is advisable to examine the coefficient of variation of the quote waits. Random arrivals typically yield a coefficient of variation around 1. For EURUSD, this value was 3.1. If the coefficient is below approximately 0.7, the feed is likely timer-driven, and a clustering model fitted to such data will only describe the timer's behavior, not actual market dynamics.

The indicator line does not decrease immediately during a sudden silence in quotes. The expected wait time is only updated when a new quote arrives. Therefore, if a period of high activity ends abruptly, the line will maintain its last recorded busy value until the next quote is received. The silence ratio, which must be calculated by the EA as described earlier, addresses this scenario.

The Weibull distribution provides an approximate fit for quote waits. Actual quote wait distributions often exhibit heavier tails than the Weibull model allows, and some residual structure may persist at lags of one and two events post-fit. While these factors do not typically affect how the gauge is interpreted, a more flexible distribution might yield slightly different alpha and beta parameters.

The evidence presented is based on thirty days of data. The relative performance of the ACD gauge versus rolling counts varied depending on the forecast horizon and asset class, and could potentially differ under different market conditions.

Tick history is required for operation. The indicator requests ten trading days of tick data upon loading. On a new terminal installation, the initial load will be delayed until this data is downloaded.

File Structure

The distribution includes one indicator file and five header files. The headers are included using the
File

Role

Description

Indicators ACD ACD_Activity.mq5

The indicator

Learns the time-of-day rhythm from historical data preceding the plotted range, then replays the plotted period quote by quote, displaying the activity ratio alongside a contrasting tick volume. It provides fixed buffers for Expert Advisors.

Include ACD AcdTypes.mqh

Shared types

Defines parameters, the fit report structure, the buffer mapping, the one-step update mechanism, helper functions for persistence and half-life calculations, and the Weibull log-density function.

Include ACD AcdEvents.mqh

Event series generation

The CAcdEvents class transforms the raw tick stream into a structured series of events, handling same-millisecond quote consolidation, identification of session gaps, and day-by-day data loading.

Include ACD AcdDiurnal.mqh

Daily rhythm modeling

The CAcdDiurnal class models the time-of-day profile, including interpolation between bin centers and scaling for unit-mean waits, supporting both pooled and per-weekday profiles.

Include ACD AcdModel.mqh

Parameter fitting

The CAcdModel class performs maximum-likelihood fitting using the Nelder-Mead method, incorporating exponential or Weibull surprises. It also provides a rhythm-only baseline model and diagnostic tools for analyzing residuals.

Include ACD AcdState.mqh

Live state tracking

The CAcdState class manages the real-time state updates, operating in constant time. It calculates the activity ratio, surprise component, expected wait time, and silence ratio.

Research Basis

The underlying model is based on the work by:

Robert F. Engle and Jeffrey R. Russell, Autoregressive Conditional Duration: A New Model for Irregularly Spaced Transaction Data, Econometrica, 1998. This paper is available on JSTOR.

This program is provided for educational and research purposes only. It is crucial to thoroughly test any application of this code on a demo account before committing real capital.

A supplementary article provides a detailed explanation of the data feed checks, the rhythm modeling, and the model's step-by-step operation. It also presents the complete volatility study results across six different symbols: Beyond Tick Volume: Measuring Market Activity from the Waits Between Quotes.

You may also like: MTF Trend Context - Professional Market Analysis Tool - excellent alternative for indicator users on MetaTrader 5.

Source Code

#property copyright "RobotFX"
#property link "https://robotfx.org"
#property version   "1.00"
#property strict
#property description "This code is educational. Feel free to use, modify and upgrade as you wish. Visit ROBOTFX.ORG for professional trading tools"
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   2
#property indicator_label1  "Activity"
#property indicator_type1   DRAW_COLOR_LINE

.......

Leave your opinion, ask a question, share some knowledge

⚠ Limitations & Risk Warning

  • This tool is provided for educational and testing purposes only.
  • Past performance does not guarantee future results.
  • Trading involves substantial risk of loss. Use on a demo account first.
  • Results may vary depending on market conditions, broker, and settings.
  • We recommend thorough backtesting and forward testing before using with real funds.
© ROBOTFX Free educational tools by RobotFX. Use entirely at your own risk; we are not liable for any financial losses incurred.