Edges
Order Flow Imbalance
A chart shows you what prices have been. Order flow shows you what participants are actively doing. The distinction matters because price is the result — the record of where trades cleared. Order flow is the cause — the accumulation of buy and sell pressure that drove the clearing price to where it went.
When buy orders substantially outnumber sell orders in a short window, the market has to move to find sellers at higher prices. When sell orders dominate, the market finds buyers at lower prices. The move happens before the completed chart pattern shows it — and that gap between cause and visible effect is where the order flow signal lives.
The honest version of this edge comes with two qualifications. First, retail traders do not have full access to order flow data. What is accessible — bid/ask size, trade tape, volume delta — is a proxy, not the complete picture. Dark pools, off-exchange internalization, and full limit order book depth are not visible to a standard retail data feed. Second, this signal decays. As algorithmic strategies proliferate and more participants incorporate the same imbalance metrics, the edge at high-frequency resolutions becomes noisier and shorter-lived. The edge is most durable at the slower end of its applicable range.
Understanding the mechanics of order flow is also useful for interpreting the momentum patterns covered in Momentum + Volume: sustained volume imbalance is part of what creates and extends the high-volume momentum moves described there.
What Order Flow Imbalance Is
Order flow imbalance is the net difference between buying pressure and selling pressure over a defined period. When buy-initiated trades exceed sell-initiated trades — more aggressive buyers lifting the offer than sellers hitting the bid — the imbalance is positive and directional pressure is upward. The converse holds for negative imbalance.
The key word is "pressure." Price does not move in strict lockstep with every imbalanced order. Market makers absorb a significant fraction of incoming order flow by adjusting their quotes rather than letting price move immediately. But when the imbalance is large enough, sustained enough, or accelerates suddenly, market makers can no longer absorb it at the current price level and the price must shift to attract counterparty interest from the other side. That shift is the directional move the signal is trying to anticipate.
Volume delta. The most common aggregate measure of order flow imbalance is volume delta: the difference between volume traded on upticks (buyer-initiated, at the ask) and volume traded on downticks (seller-initiated, at the bid), over a fixed time window or candle. A positive delta means more volume is transacting aggressively at the offer; a negative delta means more volume is transacting aggressively at the bid. Over a sequence of candles, the cumulative delta shows whether the dominant flow during a period has been net buying or net selling pressure.
The distinction from price direction. Price can move up with negative delta — if sellers are absorbing large limit orders from buyers who are lifting the offer, the price may not move at all even as substantial imbalance accumulates. When that absorbed imbalance resolves — when the limit order inventory is consumed — the price moves sharply in the direction of the prior imbalance. This is why order flow analysis can signal moves before the price chart shows them.
Why the Edge Exists
Institutional orders are large. A fund allocating 1% of a $2 billion portfolio to a single equity purchase represents $20 million in buying pressure. Executing that in a single market order would move the price significantly against the buyer. Instead, large orders are worked over time — broken into small pieces and executed across many minutes or hours using algorithmic execution strategies designed to minimize market impact.
Even with careful execution, the aggregate buying pressure from a large institutional order is visible in the trade tape and volume delta as a sustained positive imbalance. The price does not move all at once, but the imbalance accumulates. Traders monitoring order flow can observe the imbalance pattern — sustained net buying without a corresponding price move, or sustained net buying that accelerates — and position directionally before the execution program completes and the full price impact is realized.
This is not front-running. The order flow signal does not require knowledge of the institutional order. It observes the publicly available trade tape and infers that something large is working. The inference is probabilistic, not certain — the sustained imbalance could resolve without a significant price move if the institutional buyer runs out of allocation, the order is cancelled, or a counterparty emerges with equal and opposite selling pressure.
What Retail Traders Can Actually Access
The complete picture of order flow requires access to the full limit order book at every price level — which is only available to exchange members, prime brokers, and venues with co-location access to the matching engine. Retail traders do not have this.
Level 1 data. The standard retail feed includes the best bid, best ask, and their respective sizes at any moment. Bid size is the number of shares available to buy at the current best bid; ask size is the number of shares available to sell at the current best ask. The ratio between them is a shallow proxy for immediate buying versus selling pressure. If the bid size is 10,000 shares and the ask size is 500 shares, there is significant buy-side interest at the current bid relative to supply at the ask — which is one indicator of upward pressure.
Trade tape. The time and sales feed shows each executed trade: price, size, and whether it transacted at the bid or ask. A trade at the ask is buyer-initiated (aggressive buyer); a trade at the bid is seller-initiated (aggressive seller). Aggregating this data over rolling windows produces a volume delta approximation from public data.
What is not accessible. Dark pools execute a substantial fraction of daily equity volume — often 30–45% depending on the instrument — off-exchange and entirely invisible to the public tape. Retail order internalization by broker-dealers means that retail buy and sell orders are often matched internally before reaching any exchange. These flows are invisible in real time. Any signal built from the public tape is observing an incomplete picture of total order flow.
The practical implication. The proxy works because institutional order flow is large enough that even the visible fraction — the portion that does reach exchanges — creates detectable imbalance patterns. Small retail orders routed through dark pools do not create useful signal. The signal comes from large systematic flows that leave a footprint on the public tape.
How to Build a Signal from Level 1 Data
The bid/ask size imbalance is the simplest usable proxy. It measures the imbalance between current buy interest (bid) and sell interest (ask) at the inside quote.
Interpreting the ratio. A bid/ask imbalance ratio near +1 means the bid is fully dominating the inside quote — all available interest is on the buy side. A ratio near -1 means all interest is on the sell side. In practice, the ratio oscillates continuously; the signal is meaningful only when it is sustained above or below a threshold over a rolling window.
Using the uptick rule proxy. A rougher but still useful approximation of trade direction is available without a direct connection to the exchange: compare each trade's price to the previous trade's price. Trades at a higher price than the prior trade are presumed buyer-initiated (uptick rule); trades at a lower price are presumed seller-initiated. Aggregating over rolling windows produces a volume delta estimate from standard trade feed data. Modern execution algorithms are sophisticated enough that this proxy overstates the accuracy at tick-by-tick resolution, but at 1-minute and 5-minute aggregation it remains a useful directional indicator.
When It Fails
Edge decay. This is the primary risk. As more algorithmic strategies incorporate bid/ask imbalance and volume delta metrics into their signal generation, the edge at fast resolutions diminishes. When many participants are watching the same imbalance signal and acting simultaneously, the market-moving information is priced in faster. The original signal that produced a 30-second lead time may produce a 3-second lead time a year later as adoption increases. This is not a problem specific to order flow — it applies to any signal that becomes widely known — but order flow metrics at sub-minute resolution have been particularly susceptible to this decay.
HFT makes sub-second signals noisier. High-frequency trading firms are the primary market makers at ultra-short time resolutions. They continuously quote bids and asks and adjust them based on their own order flow signals, inventory management, and cross-asset hedging. The result is that the bid/ask size at Level 1 at any millisecond is not a reflection of genuine supply and demand at that price — it is partly a reflection of a market maker managing its inventory. Interpreting that inventory management as a directional signal produces false signals at high frequency.
The edge is better on slower timeframes. On 5-minute bars, the bid/ask imbalance signal is less contaminated by market-maker inventory noise and more reflective of genuine institutional and semi-institutional order flow. At the 1-minute level, it is still useful but noisier. At tick-by-tick resolution, the signal-to-noise ratio for a retail participant with a standard data feed is poor.
How to Code It in Python
import pandas as pd
def bid_ask_imbalance(bid_size: pd.Series, ask_size: pd.Series) -> pd.Series:
total = bid_size + ask_size
return (bid_size - ask_size) / total.replace(0, float('nan')) # +1 = all bids, -1 = all asks
def imbalance_signal(imbalance: pd.Series, window: int = 10, threshold: float = 0.3) -> pd.Series:
smooth = imbalance.rolling(window).mean()
signal = pd.Series(0, index=imbalance.index)
signal[smooth > threshold] = 1
signal[smooth < -threshold] = -1
return signal
bid_ask_imbalance normalizes the raw bid and ask sizes into a ratio ranging from -1 to +1. Dividing by the total prevents large absolute-size quotes from being treated as more informative than smaller-size quotes on a different instrument or at a different time of day. The .replace(0, float('nan')) handles the edge case of a zero-total quote, which can occur briefly during trading halts or at market open.
imbalance_signal applies a rolling mean over window periods to smooth out tick-level noise before applying the threshold test. With window=10, the signal requires the sustained average imbalance over 10 observations to exceed the threshold — not a single-tick spike. The threshold of 0.3 means the smoothed imbalance must be at least 30% tilted toward one side before generating a directional signal. Lower thresholds generate more signals with lower average quality; higher thresholds generate fewer signals but with more conviction.
Calibrating window to your timeframe. At 1-minute bar resolution, window=10 means 10 minutes of sustained imbalance — which is appropriate for a signal targeting 30–60 minute holding periods. At tick resolution, window=10 means 10 ticks — much too short, and the resulting signal will be noise-dominated. Match the window to the holding period: if you want to hold for 5 minutes, use a window of 5–10 periods at 1-minute resolution.
Extending to volume delta. The code above uses Level 1 quote data. If your data feed includes time and sales, the volume delta extension adds meaningful signal:
def volume_delta(prices: pd.Series, volumes: pd.Series) -> pd.Series:
direction = prices.diff().apply(lambda x: 1 if x > 0 else (-1 if x < 0 else 0))
return (volumes * direction).cumsum()
The cumulative volume delta over a session — how much net buyer-initiated volume has accumulated — tells you whether the day's price movement has been driven by genuine buying conviction or thin seller absence, which is the same distinction that volume confirmation makes for momentum signals.
The Oyamori Approach
Order flow imbalance sits at the microstructure end of the signal spectrum — faster, noisier, and more sensitive to edge decay than the macro and momentum edges elsewhere in the catalog. Oyamori incorporates it as a trade timing tool rather than a primary entry trigger: once a directional edge exists from a higher-timeframe signal, the order flow imbalance at the 1-5 minute level can improve entry timing, avoiding fills at moments when the flow is running against you.
The signal is honest about its limitations. Retail access to order flow is a proxy, not the real thing. The edge that exists at the 1-minute level for a participant with full Level 2 access and co-located execution is not the same edge available from a standard broker API. The code above builds what is buildable with accessible data; the output should be treated as one confirming input among several, not a standalone trigger.