SEQ LSTMs & Sequence Models
When order matters — modeling trade evolution and time series
Learning Objectives
- •Understand why LSTMs were designed and what problem they solve
- •Learn how to frame trading problems as sequence tasks
- •See practical LSTM applications: exit management and regime detection
- •Know the common failure modes and how to avoid them
Explain Like I'm 5
Standard neural networks see each input independently — they have no memory. LSTMs (Long Short-Term Memory networks) were designed to remember. They process sequences step by step and decide what to remember, what to forget, and what to output at each step. For trade management, the sequence of how a trade evolves bar by bar is exactly this kind of problem.
Think of It This Way
Reading a single sentence vs. reading a whole paragraph. A standard network sees one sentence and responds. An LSTM reads the whole paragraph, carrying context forward. "The stock rallied hard" means something different after "The company reported weak earnings" vs. "The company crushed expectations." Context is everything.
1The Vanishing Gradient Problem
Gradient Magnitude Over Time Steps: RNN vs LSTM
2LSTMs for Exit Management
LSTM Exit Score Over Trade Lifetime
3GRUs — The Simpler Alternative
4Common Failure Modes
LSTM Performance by Sequence Length
Key Formulas
LSTM Forget Gate
Decides what to forget from the cell state. σ outputs values between 0 (forget everything) and 1 (keep everything). The network learns which past information is relevant for the current decision.
LSTM Cell State Update
The cell state is updated by forgetting some old information (f_t × C_{t-1}) and adding new information (i_t × C̃_t). This selective memory is what prevents the vanishing gradient problem.
Hands-On Code
LSTM Exit Model
import torch
import torch.nn as nn
class ExitLSTM(nn.Module):
"""LSTM for trade exit timing (L3)."""
def __init__(self, input_dim=8, hidden_dim=64, dropout=0.3):
super().__init__()
self.lstm = nn.LSTM(
input_dim, hidden_dim,
num_layers=2,
dropout=dropout,
batch_first=True,
)
self.classifier = nn.Sequential(
nn.Linear(hidden_dim, 32),
nn.ReLU(),
nn.Dropout(dropout),
nn.Linear(32, 1),
nn.Sigmoid(),
)
def forward(self, sequence):
"""
sequence shape: (batch, seq_len, features)
Features per bar: current_r, mfe_r, mae_r, bars_held,
atr_ratio, regime_score, momentum, volume_ratio
"""
lstm_out, _ = self.lstm(sequence)
last_output = lstm_out[:, -1, :] # Use final hidden state
exit_prob = self.classifier(last_output)
return exit_prob.squeeze(-1)
# Training note:
# Each training sample is a sequence of bars for one trade
# Label: 1 = should have exited at this bar, 0 = hold
# Use walk-forward: train on trades from months 1-12,
# validate on months 13-15, test on months 16-18Two LSTM layers process the trade bar-by-bar. The final hidden state encodes the trade's full history. The classifier head converts this to an exit probability. Dropout on recurrent connections prevents overfitting to specific price patterns.
Knowledge Check
Q1.Why are LSTMs better suited for exit management than signal detection?
Assignment
Frame a trade exit problem as a sequence task. Define the per-bar features (at least 6), create training sequences from historical trades, and build a simple LSTM. Compare its exit decisions to a fixed trailing stop on the same trades.