Machine learning has revolutionized quantitative trading by enabling the discovery of complex patterns in financial data that traditional statistical methods cannot detect. This chapter covers the most effective ML architectures for trading applications.
Best For: Sequential pattern recognition, price prediction, trend analysis
Architecture: Recurrent neural network with memory cells that can learn long-term dependencies
import torch
import torch.nn as nn
class LSTMPredictor(nn.Module):
def __init__(self, input_size, hidden_size, num_layers, output_size):
super(LSTMPredictor, self).__init__()
self.lstm = nn.LSTM(input_size, hidden_size, num_layers,
batch_first=True, dropout=0.2)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
# x shape: (batch, seq_len, input_size)
lstm_out, _ = self.lstm(x)
# Take last output
predictions = self.fc(lstm_out[:, -1, :])
return predictions
# Example usage
model = LSTMPredictor(input_size=50, hidden_size=128,
num_layers=3, output_size=1)
# Input: 50 features, predict next price return
Best For: Faster training than LSTM, similar performance with fewer parameters
Architecture: Simplified version of LSTM with fewer gates, computationally more efficient
Best For: Multi-asset prediction, incorporating diverse data sources, attention mechanisms
Architecture: Self-attention mechanism that processes entire sequences in parallel
import torch.nn as nn
class TransformerPredictor(nn.Module):
def __init__(self, d_model=64, nhead=8, num_layers=6):
super().__init__()
encoder_layer = nn.TransformerEncoderLayer(
d_model=d_model, nhead=nhead,
dim_feedforward=256, dropout=0.1
)
self.transformer = nn.TransformerEncoder(
encoder_layer, num_layers=num_layers
)
self.fc = nn.Linear(d_model, 1)
def forward(self, x):
# x: (seq_len, batch, features)
transformer_out = self.transformer(x)
prediction = self.fc(transformer_out[-1])
return prediction
Predict trading signal direction: Buy (+1), Hold (0), Sell (-1)
from sklearn.ensemble import RandomForestClassifier
# Train signal classifier
rf = RandomForestClassifier(
n_estimators=500,
max_depth=10,
min_samples_split=100,
max_features='sqrt',
random_state=42
)
# Features: 100+ technical indicators
# Target: -1 (sell), 0 (hold), 1 (buy)
rf.fit(X_train, y_train)
# Feature importance
importances = rf.feature_importances_
top_features = sorted(zip(feature_names, importances),
key=lambda x: x[1], reverse=True)[:20]
Predict continuous returns for ranking and portfolio construction
import xgboost as xgb
# Predict next period return
model = xgb.XGBRegressor(
n_estimators=1000,
max_depth=6,
learning_rate=0.01,
subsample=0.8,
colsample_bytree=0.8,
gamma=1,
tree_method='gpu_hist'
)
model.fit(X_train, y_train,
eval_set=[(X_val, y_val)],
early_stopping_rounds=50,
verbose=False)
Learn optimal trading actions through trial and error
import pandas as pd
import ta # Technical analysis library
def engineer_features(df):
"""Create comprehensive feature set"""
# Price features
df['returns'] = df['close'].pct_change()
df['log_returns'] = np.log(df['close'] / df['close'].shift(1))
df['volatility'] = df['returns'].rolling(20).std()
# Technical indicators
df['rsi'] = ta.momentum.rsi(df['close'], window=14)
df['macd'] = ta.trend.macd_diff(df['close'])
df['bb_high'] = ta.volatility.bollinger_hband(df['close'])
df['bb_low'] = ta.volatility.bollinger_lband(df['close'])
# Volume indicators
df['obv'] = ta.volume.on_balance_volume(df['close'], df['volume'])
df['mfi'] = ta.volume.money_flow_index(df['high'], df['low'],
df['close'], df['volume'])
# Lag features
for lag in [1, 2, 5, 10, 20]:
df[f'return_lag_{lag}'] = df['returns'].shift(lag)
return df.dropna()
Never use random splits for time series! Use walk-forward validation: