Time-Aware One-Pass Exponential Normalisation
One of the recurring problems I encountered while building low-latency market making systems was that most online statistical algorithms assume observations arrive at regular intervals.
Financial markets simply don’t behave like that.
During active periods an exchange may produce thousands of updates every second, while during quiet periods there may be hundreds of milliseconds—or even seconds—between updates.
Traditional exponential moving averages don’t account for this.
Instead, they decay based on the number of observations, not the amount of time that has actually elapsed.
For many quantitative trading applications, especially event-driven alpha signals, this distinction matters.
This article describes a simple one-pass algorithm I developed that performs online normalisation directly using exchange timestamps.
The algorithm simultaneously computes
- Time-aware Exponentially Weighted Mean
- Time-aware Exponentially Weighted Variance
- Time-aware Z-Scores
all using constant memory and constant computational complexity.
Why Time Matters
Suppose we observe an Order Book Imbalance (OBI) signal.
A large imbalance arrives from the exchange.
Normally we compute
\[z=\frac{x-\mu}{\sigma}\]and use that as our alpha signal.
However, what happens if no further market updates arrive?
The last imbalance may have been extremely informative when it occurred, but after several seconds without updates that same imbalance becomes increasingly stale.
Traditional z-scores never account for this.
My algorithm does.
Computing the Time-Aware Weight
Rather than using a fixed smoothing parameter,
\[\alpha\]I compute the exponential weight directly from the elapsed time.
Let
- $(T_{1/2})$ be the chosen half-life
- $(\Delta t)$ be the elapsed time between observations
Then
\[w = 2^{-\Delta t/T_{1/2}}\]This has several useful properties.
If updates arrive extremely quickly,
\[\Delta t\rightarrow0\]then
\[w\rightarrow1.\]Very little forgetting occurs.
If updates arrive after a long delay,
\[\Delta t\gg T_{1/2}\]then
\[w\rightarrow0.\]Old information is naturally forgotten.
The estimator therefore has a memory measured in seconds, not market messages.
One-Pass Exponential Mean
The exponentially weighted mean becomes
\[\mu_t = w\mu_{t-1} + (1-w)x_t.\]Only the previous mean needs to be stored.
Memory complexity is therefore
O(1)
One-Pass Exponential Variance
The variance is updated simultaneously
\[\sigma_t^2 = w\sigma_{t-1}^2 + (1-w) (x_t-\mu_{t-1}) (x_t-\mu_t).\]Unlike rolling windows, no historical observations are stored.
Everything is updated in one pass.
Again,
Memory : O(1)
Runtime : O(1)
per market update.
Separate Half-Lives
One extension I have found particularly useful is using different half-lives for the mean and variance.
Instead of
HalfLife
we define
MeanHalfLife
VarianceHalfLife
The intuition is simple.
Market prices can change direction quickly.
Market volatility often persists much longer.
Using a slower variance estimate generally produces a much more stable z-score while allowing the mean to remain responsive.
This becomes another parameter that can be optimised during model fitting.
Time-Aware Z-Scores
After computing the mean and variance,
the raw z-score becomes
\[z = \frac{x-\mu}{\sigma}.\]But the interesting part happens between observations.
Suppose no new market updates arrive.
Rather than leaving the z-score unchanged,
I simply decay it using exactly the same exponential weighting.
\[z_{current} = 2^{-\Delta t/T_{1/2}} z_{last}.\]This means a
+3σ
order book imbalance slowly returns toward zero if nothing else happens.
Conceptually we are no longer asking
“How unusual was the last observation?”
Instead we are asking
“How informative is the latest observation right now?”
This distinction becomes extremely important when building event-driven alpha signals.
Why Exchange Timestamps?
One feature I particularly like is that the algorithm uses exchange timestamps, not local timestamps.
Suppose the exchange generated a message
5 ms
before we received it.
That message is already
5 ms
old.
Using exchange timestamps means the statistical decay naturally incorporates
- exchange processing delay
- network latency
- market data propagation delay
into the model.
This becomes extremely useful for lead-lag modelling.
Two exchanges may publish information at different times.
By using exchange timestamps directly, the algorithm automatically discounts stale information.
The resulting alpha signals more accurately reflect what the market actually knew at a particular point in time.
Computational Performance
The algorithm is designed specifically for low-latency systems.
Each update performs only
- one exponential
- a handful of additions
- several multiplications
- one square root
- one division
There are
- no rolling windows
- no dynamic memory allocation
- no historical arrays
- no garbage collection
The update cost is completely deterministic.
Memory Complexity : O(1)
Time Complexity : O(1)
which makes it ideal for high-frequency trading applications where millions of updates per second may need to be processed.
Bounded Features
Raw z-scores are theoretically unbounded.
During extreme market events values of
10σ
20σ
are entirely possible.
Rather than feeding these directly into a machine learning model,
I squash the z-score using
\[\tanh\left(\frac{z}{3}\right)\]which maps every feature into
\[[-1,+1].\]This produces several useful properties.
- Outliers become compressed.
- Features become directly comparable.
- Numerical optimisation becomes more stable.
- Every feature has approximately the same scale.
This is particularly useful for linear models.
Building Alpha Signals
After normalisation,
every feature becomes
\[x_i\in[-1,+1].\]A feature vector is then simply
\[X= (x_1,x_2,\ldots,x_n).\]This can be fed directly into an online linear regression model,
\[\hat y = \beta_0 + \sum_i \beta_i x_i,\]where
\[\hat y\]represents an exponentially discounted future mid-price markout.
One of the major advantages of linear regression is interpretability.
Every fitted coefficient tells us how informative that feature is for predicting future returns.
Features with coefficients close to zero contribute very little.
Large positive or negative coefficients indicate features with stronger predictive power.
Because every feature has already been normalised into the same numerical range, coefficient magnitudes become directly comparable.
This makes feature selection significantly easier.
Applications
Although this algorithm was originally developed for Order Book Imbalance, it naturally extends to many other market features.
Examples include
- Order Book Imbalance
- Trade Intensity
- Trade Flow Imbalance
- Exchange Latency
- Spread
- Microprice
- Lead-Lag Relationships
- Basis Signals
- Cross-Exchange Price Differences
Essentially any event-driven feature can be transformed into a bounded, time-aware statistical signal.
Summary
This algorithm provides a simple framework for performing online statistical normalisation in event-driven markets.
Its main advantages are
- Uses exchange timestamps directly.
- Naturally handles irregular market updates.
- Constant memory usage.
- Constant computational complexity.
- Time-aware exponential forgetting.
- Decaying confidence between observations.
- Produces bounded machine-learning-ready features.
- Integrates naturally with online linear and logistic regression models.
For me, this has become the statistical foundation for building low-latency alpha signals.
Rather than thinking in terms of how many observations have occurred, the algorithm instead measures how much real time has elapsed.
In fast electronic markets, I believe this is a much more natural way to model the information content of market data.