This article addresses a specific paradigm: event-driven directional trading with ML-based filtering. The pipeline detects discrete setup events, computes point-in-time features, predicts a binary outcome (e.g., take-profit vs. stop-loss via triple-barrier labeling), and sizes positions based on model confidence.
This is not the only way to apply ML in finance. It does not cover:
- Statistical arbitrage / pairs trading: continuous rebalancing based on spread models, no discrete event trigger
- Market making: inventory management and spread optimization, different objective entirely
- Portfolio optimization: asset allocation, risk parity, mean-variance (operates on a different timescale and problem formulation)
- Alpha factor research: cross-sectional ranking across asset universes on regular rebalancing schedules, not event-triggered
- Execution algorithms: TWAP/VWAP, optimal execution (the trade decision is already made, ML optimizes how)
In the event-driven paradigm, the model's job is binary classification at discrete moments: "given this setup, should I trade or not?" The event sampler determines which moments those are. Everything in this article follows from that framing.
The Default Approach and Why It Doesn't Work
The standard pipeline in this paradigm looks like this:
- Pick a signal (MA cross, RSI threshold, pattern match)
- Compute features at each signal timestamp
- Label outcomes (triple-barrier or similar)
- Train a classifier
- Evaluate
This often fails. The typical result is test accuracy near 50% that doesn't meaningfully improve with model complexity, feature count, or hyperparameter tuning. Permutation tests struggle to reject the null. Confidence thresholding shows weak or no ranking ability.
The instinct is to blame the features or the model. Add more features. Try deeper trees. Stack ensembles. This is wrong. The problem is upstream of all of it.
The problem is the event sampler.
Why Event-Based Sampling
Most ML approaches in this paradigm default to fixed-interval sampling: compute features every bar (or every N bars), predict direction, repeat. This forces the model to answer "what will price do next?" at every timestep, including the vast majority of moments where the honest answer is "nothing structurally interesting."
This creates the timing problem. The model must simultaneously learn (a) whether now is a good time to trade at all, and (b) which direction. Task (a) dominates (most bars are noise), so the model spends its capacity learning "don't trade" and has little left for the directional signal that matters.
Event-based sampling eliminates task (a) by construction. The sampler pre-filters timestamps to moments where a specific market mechanism has activated. The model only sees moments where something structural is happening. Its entire capacity goes toward the directional question.
This is also why event-based systems compose well with bet sizing and meta-modeling. The sampler says "now." The primary model says "which direction." The meta-model says "how confident." Each component has a single, well-scoped job instead of one model trying to learn everything from a stream of mostly-empty bars.
What an Event Sampler Actually Does
The sampler determines WHEN the model is asked to make a prediction. Every observation in your training set exists because the sampler said "this is a moment worth evaluating."
If the sampler fires at moments with no structural significance (moments that are statistically indistinguishable from random timestamps), then features computed at those moments are random numbers, labels are coin flips, and no model can learn anything stable.
This is exactly what happens with common technical signals. An MA cross fires when a lagging average of past prices crosses another lagging average of past prices. The cross is a summary of what already happened. Nothing in the market's microstructure responds to the cross itself. No stops are triggered. No orders activate. No liquidity event occurs. The cross is an observation, not a trigger.
The distinction matters: for features at a timestamp to carry information about the outcome, the event must be connected to the outcome through some mechanism, not just correlated with it in-sample.
When Observation-Based ML Appears to Work
When an observation-based system (e.g., MA cross + gradient boosting) does produce out-of-sample signal, it is typically for one of two reasons: either the observation coincidentally overlaps with a mechanical trigger (an MA cross near a swing level where stops cluster, where the cross isn't the trigger, the level breach is, but they fire simultaneously), or the model learns through features to suppress most firing times and only act on the subset that happens to coincide with structural activity, effectively reconstructing a trigger filter internally, but wasting model capacity to do so.
Why Observations Aren't Sufficient
The core issue is identifiability of the data-generating process. At a trigger point, the outcome is generated by a specific mechanism (stop cascade, liquidation, forced unwind) whose causal variables are partially observable, so the conditional distribution P(Y|X) has structure because you know which process is active. At an arbitrary observation point, the outcome is generated by whatever happens next in the market: an unbounded mixture of mechanisms with unknown, time-varying mixture weights. The model must simultaneously identify which process is active and estimate within it, a strictly harder problem that demands exponentially more data or strong structural priors.
This is not a new insight. De Prado (2018) argues in Advances in Financial Machine Learning that fixed-interval (time) bars are statistically inferior because they sample at arbitrary moments unrelated to information arrival. His alternative, information-driven bars (volume bars, dollar bars, tick bars), samples when a threshold amount of market activity has occurred, ensuring each observation reflects a comparable quantum of participation. His CUSUM filter goes further: it fires only when cumulative price deviation from expectation exceeds a threshold, acting as a structural break detector that explicitly avoids sampling during drift.
Easley, Lopez de Prado & O'Hara (2012) formalize this through VPIN (Volume-Synchronized Probability of Informed Trading), showing that sampling synchronized to volume rather than time better captures information arrival. The earlier sequential trade models of Easley & O'Hara (1987, 1992) established that the arrival process of trades itself carries information, and clock-time sampling destroys this signal by ignoring the rate at which participation occurs.
The common thread: sampling should be conditioned on sufficient, consistent participation (evidence that a specific market mechanism is active), not on the passage of time or the crossing of a derived indicator.
The Causal Requirement
For an event sampler to produce learnable data, couple of conditions must hold:
1. The event must trigger a mechanical process in the market.
"Trigger" means the event itself causes order flow. Not "is correlated with future price movement", causes it. When price breaks a level where stops are clustered, those stops are market orders that hit the book. That's a mechanical trigger. When RSI crosses 70, nothing fires in any order book anywhere. That's an observation.
The trigger creates the outcome space. Without it, there is no process to predict.
2. The outcome of that process must depend on partially observable variables.
The triggered process (say, a stop cascade) can result in continuation or reversal. Which one occurs depends on variables like: how much counter-liquidity is resting on the other side, whether the flow is informed or mechanical, what the broader regime is. These are the causal variables.
If these variables were completely unobservable, ML couldn't help. If they were fully observable, you wouldn't need ML. The sweet spot: partially observable through computable proxies. Volume proxies for flow intensity. Volatility regime proxies for liquidity depth. Time-of-day proxies for participant composition.
3. The causal relationship must be stable (stationary).
The mechanism connecting trigger → causal variables → outcome must persist across time. Mechanisms rooted in market microstructure (order books exist, stops exist, margin exists, liquidity varies) are structural. They persist because they arise from the architecture of markets, not from a temporary statistical pattern.
Mechanisms rooted in price patterns (head and shoulders, double tops as visual shapes, indicator thresholds) are fragile. They work until participants adapt, then they stop.
4. The event must generate sufficient sample frequency.
A valid causal mechanism is useless if it fires twice a year. ML needs enough observations to estimate f() reliably and to validate that estimate out-of-sample. Fewer events means wider confidence intervals, more overfit risk, and inability to distinguish signal from noise in cross-validation.
This creates a tension: more selective samplers have cleaner causal structure but fewer events. Too selective and you can't train. Too frequent and you're back to noise. The practical target is an event that fires often enough because the underlying mechanism is common (liquidity events happen daily), not because the definition is loose.
5. The causal graph must persist across instruments.
If the mechanism is truly structural (rooted in how order books, stops, and margin work), it should produce learnable signal across multiple instruments, not just one. A sampler that works on BTC but fails on ETH and SOL is likely fitting BTC-specific noise, not capturing a general microstructure mechanism.
This is a strong test. Stops cluster at swing points on every liquid instrument. Volatility compresses and expands on every instrument. Liquidation cascades happen on every leveraged market. If the causal graph is real, the same features should have non-trivial importance across pairs (not identical coefficients, but the same variables mattering).
Cross-pair consistency also multiplies your effective sample size. Five pairs with 400 events each give you 2000 observations sharing the same causal structure, enabling more robust estimation than 400 observations from one pair with five times the features.
The Causal Skeleton
a valid sampler maps to the directed acyclic graph:
Market structure generates identifiable levels/states
→ Orders accumulate mechanically around these levels
→ Price reaches the level (TRIGGER)
→ Accumulated orders fire (CASCADE)
→ Outcome = f(counter-liquidity, flow quality, regime)
ML estimates f(). Features are proxies for the arguments of f().
This skeleton has three important properties:
Directionality. The arrow goes from structure → accumulation → trigger → cascade → outcome. Not backwards. The trigger causes the cascade; the cascade determines the outcome. This is why the sampler must be a trigger, not an observation (observations sit outside the causal graph).
Identifiable intervention points. The causal variables (counter-liquidity, flow quality, regime) are the points where the system can branch. If counter-liquidity is deep, the cascade is absorbed. If it's thin, it continues. Features that proxy for these branch points carry genuine information about the outcome.
Testable predictions. If the causal model is correct:
- Features proxying causal variables should have non-trivial importance
- Importance should be stable across time periods (the mechanism persists)
- Permutation tests should reject the null (features carry real signal)
- Thresholding on model confidence should show monotonic accuracy improvement (the model's confidence reflects real variation in causal variable states)
If any of these fail, either the causal model is wrong or the features don't proxy what you think they proxy.
Evaluating a Sampler Before Building the Full Pipeline
Before committing to validation infrastructure, run the sampler through a sanity check that tests the causal predictions:
-
Baseline accuracy > 50%. If the raw event has no directional bias, ML has to create edge from features alone. Possible but hard. A sampler where the base rate is 52-55% in the direction of the trigger gives ML a realistic job (filter good setups from bad ones, not create signal from nothing).
-
Feature importance is non-uniform. If the causal model is correct, features proxying causal variables should dominate. Flat importance = features aren't connected to the outcome mechanism.
-
Importance is stable across folds. If the same features are important in fold 1 and fold 5, the mechanism is consistent over time. If importance shuffles randomly, the model is fitting noise.
-
Confidence thresholding is monotonic. If the model's predicted probability reflects real variation in causal states, higher confidence should correspond to higher accuracy. Flat thresholding = the model has no ranking ability = features don't proxy the causal variables.
-
Permutation test rejects null. Shuffled labels should destroy performance. If they don't, the original performance was noise.
A sampler that fails these checks has no causal structure worth modeling. Move on to the next candidate rather than engineering more features or tuning harder.
The Counterparty Question
A sampler with a valid causal mechanism still needs an economic answer to: who is losing money on the other side, and why do they keep doing it?
In structural liquidity events, the counterparties are identifiable:
- Stop-loss traders who placed stops at visible levels because risk management requires it. They'll keep doing it because the alternative (no stops) is worse.
- Late momentum traders who entered crowded positions. They keep doing it because FOMO and recency bias are persistent behavioral patterns.
- Forced liquidations from leveraged participants. They keep happening because leverage is structural to derivatives markets.
- Market makers who provide liquidity and occasionally get adversely selected. They keep doing it because market making is profitable on average.
If you can't identify the counterparty, the edge is probably not real.
Event Sampling as a Tractability Choice
Event-driven sampling is not the only valid approach to ML in trading. It is the approach that makes the ML problem tractable at practical scale.
Fixed-interval sampling pushes the "when to trade" problem into the model. This can work: firms with massive cross-sectional data (thousands of equities), decades of history, and infrastructure to support hundreds of features can afford to let the model spend capacity on timing. The model internally learns regime filters, activity filters, and structural context, effectively reconstructing event detection from raw features. This is expensive in data and compute, but not impossible.
Event sampling solves the timing problem architecturally. By conditioning on moments where a known mechanism is active, it reduces the ML task to a well-posed classification: given that this specific process has triggered, what is the likely outcome? The model's entire capacity goes to the directional question. This is why event-driven systems can work with hundreds of events per pair rather than millions of cross-sectional observations, because the problem is smaller when the sampler has already done the hardest part.
The claim is not that triggers are necessary. The claim is that for the scale most practitioners operate at (single or few instruments, limited history, modest feature sets), event sampling is what makes the problem feasible. It is a structural advantage, not the only path.
Summary
The event sampler is the foundation of any event-driven ML trading system. If the sampler fires at causally meaningless moments, nothing downstream can compensate.
Features are proxies for the unobserved causal variables. Models estimate the function from proxies to outcome. This is well-posed only when the causal chain from trigger to outcome exists and is grounded in market microstructure.
This is not the only way to apply ML in trading. Fixed-interval approaches can work given sufficient data, compute, and cross-sectional breadth. But event sampling makes the problem tractable at practical scale by solving the timing question architecturally rather than forcing the model to learn it from data.
And last but not least, test the causal predictions empirically before investing in infrastructure. If the sanity check shows null signal, the causal model is wrong, not the features, not the model, not the hyperparameters. If it works on one pair but not others, the mechanism is probably not real.