By now you’ve met two ways to make a network remember the past. The RNN/LSTM/GRU threads a single hidden state through time like a game of telephone — every step whispers to the next, and gradients fade out over the chain (lesson 2’s vanishing-gradient problem). The Temporal Convolutional Network instead stacks dilated, causal convolutions to widen a fixed receptive field (lesson 3) — fast and parallel, but the horizon is whatever you hard-wired into the dilation schedule.
Attention is the third answer, and it’s almost insultingly direct: don’t thread memory, and don’t widen a window — just let every time step look directly at every other time step and decide for itself who matters. No chain to decay through. No fixed window to outgrow. Step 200 can read step 1 in a single hop. That’s the whole trick, and the Transformer is what you get when you build an entire architecture out of nothing but that trick.
Let’s earn it.
Self-attention: who looks at whom
Before you read — take a guess
Before we define anything: in self-attention, what does each output position actually compute?
The analogy. Picture a trading desk meeting. You (the query) ask a question: “what’s relevant to where price goes next?” Every analyst in the room has a name tag (a key) describing what they know, and a briefing (a value) they’ll hand over. You glance at every name tag, score how well each matches your question, turn those scores into attention percentages, and walk out with a blend of briefings weighted by relevance. Self-attention is that meeting, run for every time step at once, with every step playing both analyst and asker.
Precise definition. Each input token (say, the feature vector at time ) is linearly projected into three vectors: a query , a key , and a value , via learned matrices . Stack them into matrices . Scaled dot-product attention is:
The matrix holds every query-key dot product (the raw relevance scores). Dividing by — where is the key dimension — rescales those scores. The softmax turns each row into a probability distribution that sums to 1, and multiplying by produces the weighted average of value vectors.
Why ? If and are roughly independent unit-variance entries, their dot product has variance about — so it grows with dimension. Large scores push the softmax into saturation: one weight goes to ~1, the rest to ~0, and the gradient through softmax nearly vanishes. Dividing by pulls the variance back to roughly 1, keeping the softmax in its responsive, well-conditioned regime.
Worked example — a tiny 3-key softmax. One query attends to three keys with , so . Suppose the raw dot products are , , .
Scale each by : scaled scores are .
Exponentiate: , , . Sum .
Normalize: , , (sums to 1.000).
Now blend the value vectors. Say , , . The output is
Notice the output leans heavily on (the best-matching key) but isn’t a hard pick — it’s a soft, differentiable blend. Now compare what happens without scaling: the unscaled scores give , , , weights — the softmax has nearly collapsed onto key 1, throwing away most of the relevance structure and flattening the gradient. That’s exactly the saturation is there to prevent.
For markets we add a causal mask: an output at time may only attend to keys at times (you can’t peek at the future). In the score matrix that zeroes out the upper triangle before the softmax, so future positions get weight 0.
A causal T×T self-attention matrix. Each row is one output (query) step; columns are the input (key) steps it attends to; the upper triangle is masked (no peeking at the future) and every row's weights softmax-sum to 1. Flip between a 'Recent (momentum)' pattern that hugs the diagonal, an 'Event-driven' pattern that spikes on one past bar, and a 'Diffuse' pattern that spreads attention; then drag the softmax-temperature slider and watch the effective number of keys attended expand or collapse.
Softmax weights are not feature importances
A high attention weight means “this position was useful for blending the value vectors here”, not “this input causes the target.” Attention maps are seductive — they look like an explanation — but they’re computed from learned projections, are not unique (you can permute heads and rescale), and famously do not equal causal attribution. Treat a pretty heatmap as a debugging hint, never as evidence that bar 37 drives the next return.
When to use it
Reach for self-attention when relevance is content-dependent and irregular — when which past bar matters depends on what happened, not on a fixed lag. An earnings surprise, a regime break, or a specific level being retested are things attention can route to directly. If the dependency is a smooth, fixed-lag decay (yesterday matters most, then the day before, monotonically), a cheap exponential filter or a small AR term may match it with a fraction of the parameters — don’t summon a Transformer to relearn a moving average.
Fill in the scaling rationale.
Pick the right option for each blank, then check.
We divide the raw scores by √(d_k) so the softmax does not , which would flatten the gradient and discard relevance structure.
Why attention beats recurrence for long range
Before you read — take a guess
Two positions are 200 steps apart. How many computational hops does the signal travel between them in self-attention versus in a vanilla RNN?
The analogy. The RNN is a message passed hand-to-hand down a line of 200 people — by the end it’s “purple monkey dishwasher,” and each handoff multiplies in another Jacobian factor, so the gradient either vanishes or explodes (exactly the failure from lesson 2). Attention is a group chat: position 200 @-mentions position 1 directly, and the message arrives intact in one hop.
Precise statement. Define maximum path length as the longest distance, in computational steps, that information must travel between any two input positions for them to interact. For a recurrent net, two positions and interact only through the chain of hidden states between them, so the path length is , up to . For self-attention, every position attends to every other in a single layer, so the path length is — independent of . Short paths mean gradients don’t have to survive a long product of Jacobians, so long-range learning doesn’t decay.
The bill arrives as compute and memory. The score matrix is , so self-attention costs time and memory. Double the sequence length and the attention cost quadruples.
Worked example — counting the cost. Take bars and model width .
- RNN sequential path between the first and last bar: hops; the operation count to process the sequence is , but it’s sequential — step waits for step .
- Self-attention path between any two bars: hop; the dominant cost is — about 8× the RNN’s arithmetic here, but fully parallel across positions (one big matmul, no waiting).
So attention trades more (parallelizable) arithmetic for a vastly shorter gradient path and no sequential bottleneck. On modern hardware the parallelism usually wins on wall-clock, right up until gets large enough that the memory term bites.
The contrast made visual: the recurrent unroll threads one hidden state down the chain, and the memory-retention bar decays the further back you ask it to remember — that decay IS the vanishing gradient. Self-attention would replace this entire chain with a single direct edge from step i to step j. One hop, no decay.
| Property | RNN / LSTM | TCN | Transformer |
|---|---|---|---|
| Max path length between positions | (dilated) | ||
| Parallelism over time | None (sequential) | Full | Full |
| Compute per layer | |||
| Memory horizon | Soft, decays (gating helps) | Fixed by dilation schedule | Whole sequence, content-addressed |
| Main failure mode | Vanishing/exploding gradient | Outgrows fixed receptive field | cost + data hunger |
O(1) path length is not O(1) compute
“Constant path length” sounds like a free lunch — it isn’t. The short gradient path is bought with quadratic compute and memory in sequence length. On long financial sequences (think tick data over a full session) the memory term is the real constraint, and it’s why production setups reach for windowing, chunking, or efficient-attention variants. Don’t confuse the learning advantage (short paths) with a cost advantage (there isn’t one).
When to use it
Prefer attention over recurrence when the dependency is genuinely long-range and content-routed, and your sequences are short enough that is affordable. If is small (a handful of lags) and the signal is local, an LSTM or a TCN is cheaper and harder to overfit. If is enormous and the dependency is mostly local with rare long jumps, a TCN’s logarithmic-depth receptive field is often the sweet spot.
Pick a term, then click its definition.
Multi-head attention & positional encoding
Before you read — take a guess
Self-attention computes a weighted average over positions. What does that imply if you shuffle the order of the input bars before adding any position information?
The analogy for heads. One analyst can only hold one thesis at a time. A desk hires several — a momentum specialist, an events specialist, a liquidity specialist — and each reads the same tape through a different lens, then you pool their notes. Multi-head attention runs attention computations in parallel, each with its own lower-dimensional projections, and concatenates the results through an output projection. One head can learn to track recent drift, another to spike on a specific past event, another to watch a level.
Precise definition. With model dimension split across heads, each head works in dimension :
Splitting the budget keeps total cost roughly the same as single-head while letting heads specialize.
Positional encoding. Because attention is permutation-invariant, we add a position-dependent vector to each token’s embedding so identical features at different times are distinguishable. Sinusoidal encodings use
giving each position a unique multi-frequency fingerprint; learned positional embeddings are a trained lookup table instead. Either way, the model now knows when each token sat.
Worked mini-example — why order matters for returns. Consider two day-return sequences built from the same multiset of moves :
- Sequence A: then . Cumulative wealth: (down 0.25%).
- Sequence B: then . Cumulative wealth: (also down 0.25%).
Compounding happens to commute here, so the terminal wealth is identical — but the path is not, and path is what risk lives on. Sequence A drew down to 1.05 then fell; Sequence B drew down to 0.95 first. A momentum signal, a trailing stop, a margin call, or a volatility estimate all read these two as different worlds. A model that can’t tell A from B (no positional info) literally cannot represent “the drop came first.” Order is not decoration; it’s signal.
Sort each statement under the mechanism it describes.
Place each item in the right group.
- Splits d_model into h lower-dimensional projections, then concatenates
- Injects 'when' so permuting inputs no longer leaves outputs unchanged
- Lets one sub-computation track momentum while another spikes on a past event
- Can be sinusoidal multi-frequency or a learned lookup table
Heads do not come pre-labeled 'momentum' and 'events'
It’s tempting to narrate “head 3 is the earnings head.” In practice head roles are emergent, entangled, and often redundant — pruning studies routinely delete a chunk of heads with negligible loss. Don’t hard-code an interpretation of a head into your research story, and don’t trust that a head you eyeballed as “the event head” will play that role on out-of-sample data or after a retrain.
When to use it
Use multiple heads whenever you suspect several distinct relational patterns coexist (trend, mean-reversion, event-response) — it’s nearly free given a fixed . Always include positional encoding for time series; the only time you’d drop it is for genuinely orderless set inputs (e.g. attending across the cross-section of assets at a single timestamp, where there is no intrinsic order to encode).
If terminal wealth is identical for both orderings, why does a model still need positional information?
Answer. Because almost everything we actually care about in finance is path-dependent, even when the endpoint isn’t. Drawdown, trailing stops, margin calls, realized volatility, and any momentum or autocorrelation signal all read the two orderings as different states of the world. Self-attention without positional encoding sees both sequences as the same set of returns and is structurally incapable of distinguishing “the crash came first” from “the rally came first.” Positional encoding restores that distinction.
Transformers on the limit order book
Before you read — take a guess
Lesson 1 argued deep learning earns its keep on high signal-to-noise subproblems. Which task best fits a Transformer's appetite?
The analogy. Forecasting next year’s return from a few yearly observations is like predicting a coin’s lifetime average from three flips — mostly noise. Nowcasting the next mid-price tick from the live order book is more like reading a crowded auction room in real time: the bids and offers are right there, stacked and quantified, and the next move is mechanically related to that pressure. That’s the high-SNR, data-rich regime lesson 1 said DL was built for.
The limit order book (LOB) as input. At each instant the book lists the best price levels on each side with their resting sizes. A standard DeepLOB-style input is the top levels: for each level, the bid price, bid size, ask price, ask size — features per snapshot — stacked over a window of, say, the last 100 snapshots. This is a structured, normalized, high-frequency tensor, not a handful of noisy daily bars.
The labels. Define the mid-price . To denoise the tick-level wiggle, compare smoothed means before and after: let be the average mid over the previous ticks and the average over the next . The label is the sign of the smoothed change against a threshold :
A three-class up/flat/down classification over a horizon of a few ticks.
Worked example — labeling one event. Best bid , best ask , so . Over the previous ticks the mid averaged ; over the next 5 it averages . The smoothed return is basis points. With a threshold bp, , so this snapshot is labeled up. Had (a bp move), , it would be flat — the threshold absorbs micro-noise so the model isn’t trained to chase rounding.
The DeepLOB lineage. The influential recipe (Zhang, Zohren & Roberts, 2019) is a stack: convolutions over the price/volume levels first compress the 40-feature snapshot into local microstructure features (treating adjacent levels like adjacent pixels), an inception module captures multi-scale patterns, and then a temporal model — originally an LSTM, in later variants an attention/Transformer block — integrates over the time window before a softmax over up/flat/down. Attention’s role: route the prediction to the moments in the recent book that actually mattered (a big sweep, a sudden imbalance) rather than smearing across the window.
| LOB nowcasting | Daily-return forecasting | |
|---|---|---|
| Signal-to-noise | High (next tick ≈ current pressure) | Brutally low |
| Sample count | Millions of snapshots/day | Hundreds of obs/year |
| Horizon | A few ticks / milliseconds | Days to years |
| Label | Mechanical, smoothed mid move | Dominated by unforecastable noise |
| DL verdict (lesson 1) | Plays to DL’s strengths | Plays to DL’s weaknesses |
LOB success does not generalize up to daily returns
DeepLOB-style results are real — but they live in a specific regime: ultra-short horizon, enormous sample counts, high SNR. People routinely (and wrongly) cite them as proof that “Transformers beat classical models in finance,” then bolt the same architecture onto daily or weekly returns and faceplant. Nowcasting microstructure and forecasting macro returns are different sports. Worse, intraday LOB results that ignore latency, queue position, and transaction costs can be untradeable even when the classification accuracy is genuine.
When to use it
Deploy a Transformer-on-LOB when you have genuine high-frequency book data, a short horizon, and millions of labeled snapshots — and when your backtest models latency, fees, and fill realism honestly. Do not transplant the architecture to low-frequency return forecasting and expect the magic to follow; there the data is too scarce and too noisy for the model’s capacity, which is exactly the next section’s problem.
Fill in the regime where LOB Transformers earn their keep.
Pick the right option for each blank, then check.
The DeepLOB task works because mid-price nowcasting is a problem, the opposite of forecasting daily returns from a few hundred yearly observations.
The data-hunger problem
Before you read — take a guess
Among RNNs, TCNs, and Transformers, why does the Transformer tend to overfit fastest on small return datasets?
The analogy. A convolution arrives with an opinion (“nearby things relate”), and recurrence arrives with another (“time is a chain”) — these inductive biases are guardrails that constrain what the model can fit. A Transformer arrives with almost no opinion: any position can relate to any position, learned freely. Maximum flexibility is a superpower when data is abundant and a curse when it’s scarce. On a few hundred noisy yearly returns, a bias-free, parameter-heavy model is a sponge that soaks up noise and calls it signal.
Precise statement. Generalization error decomposes loosely as bias plus variance. Strong inductive bias lowers variance at the cost of some bias; the Transformer’s weak bias and large parameter count maximize variance, and variance is governed by the ratio of to the effective number of independent samples . Financial return series have a tiny effective (overlapping, autocorrelated, regime-shifting), so is enormous and the model overfits before it generalizes.
Worked example — the parameter-to-sample ratio. Suppose a modest Transformer block has parameters and you train on 20 years of daily equity returns: observations — and because returns are serially correlated and regimes overlap, the effective independent sample count might be closer to a few hundred. Take . Then parameters per effective sample. A healthy supervised setup wants that ratio well below 1. At 800-to-1 the model can fit the training set perfectly and learn essentially nothing that survives out of sample.
Remedies.
| Remedy | What it does | Cost / caveat |
|---|---|---|
| Heavy regularization (dropout, weight decay, early stopping) | Shrinks effective capacity | Tuning each setting is itself a trial (see below) |
| Pretraining / transfer | Learns structure from a large related corpus, fine-tunes on the small target | Pretraining data must be relevant; regime mismatch hurts |
| Simpler model | Lower , stronger bias (LSTM, TCN, or just a linear model) | May underfit genuine long-range structure |
| Pool the cross-section | Train one model across many assets to raise effective | Assumes shared dynamics; leaks if not aligned in time |
Every architecture you try inflates your trial count
Here’s the trap that sinks careers: you try a 4-head model, then 8 heads, then add a layer, then swap sinusoidal for learned encodings, then tune dropout — and quietly run dozens of configurations against the same data. Each one is a trial, and the more trials you run, the higher the best-looking Sharpe you’ll find by pure luck. This is exactly the multiple-testing problem from Machine Learning for Alpha: you must deflate your Sharpe by the number of trials. A Transformer’s huge design space makes it a multiple-testing minefield — the architecture search itself manufactures false discoveries. Pre-register your design and count every variant.
When to use it
Use a Transformer for return prediction only when you can honestly raise the effective sample count — pooling a broad cross-section, leaning on relevant pretraining, or working in a high-frequency regime with millions of snapshots. Otherwise, the smaller-bias-stronger model (or even a regularized linear model) usually wins out of sample, and you’ve spent far fewer trials getting there. The sober bottom line — which lesson 6 will hammer — is that architecture rarely rescues a low-SNR, data-starved problem; matching model capacity to genuine information content is the whole game.
Each lever below either raises effective sample size or shrinks effective capacity. Sort them.
Place each item in the right group.
- Pool training across a broad cross-section of assets
- Swap the Transformer for a smaller LSTM or TCN
- Apply dropout, weight decay, and early stopping
- Pretrain on a large related corpus, then fine-tune
Recap
Big picture
Attention & Transformers for markets
- Attention & Transformers
- Self-attention
- Query / key / value blend
- softmax(QKᵀ/√dₖ)V
- √dₖ prevents softmax saturation
- Causal mask: no future peeking
- Why it beats recurrence
- Path length O(1) vs O(T)
- No vanishing gradient (lesson 2)
- Cost: O(T²) compute & memory
- Multi-head + position
- Heads = parallel relational views
- Permutation-invariant → need positional encoding
- Sinusoidal or learned
- LOB transformers
- Top-N bid/ask price & size
- Label: smoothed mid up/flat/down
- DeepLOB: conv → inception → temporal
- High-SNR nowcasting (lesson 1)
- Data hunger
- Most params, least inductive bias
- P/N huge on returns → overfit
- Each variant inflates trial count
- Pretrain / pool / regularize / simplify
- Self-attention
Attention & Transformers — check yourself
A query attends to two keys with d_k = 4. The raw dot products are 6 and 2. After scaling by √dₖ, what are the scaled scores fed to the softmax?
Check your answer to continue.