PIP The Multi-Layer ML Pipeline
Why one model isn't enough — separation of concerns for trading
Learning Objectives
- •Understand why production trading systems use multiple model layers
- •Learn the signal → filter → exit architecture pattern
- •See how separation of concerns improves each component independently
- •Compare single-model vs multi-layer system performance characteristics
Explain Like I'm 5
Imagine hiring one person to find investment ideas, decide when to act, and manage every trade until it closes. They'd be mediocre at everything. Now hire three specialists — one for each job. Each one can be world-class at their specific task. That's the multi-layer pipeline.
Think of It This Way
A hospital doesn't have one doctor who diagnoses, operates, and does rehab. They have specialists at each stage because the skills are completely different. Same logic applies to trading: finding a signal, timing the entry, and managing the exit are fundamentally different problems that deserve different models.
1Why One Model Isn't Enough
2The Three Layers
Signal Funnel: How Candidates Get Filtered
3Single-Model vs Multi-Layer — The Numbers
Equity Curve: Single Model vs Multi-Layer Pipeline (Normalized)
4Practical Considerations
5Why This Architecture Scales
Key Formulas
L1 Signal Probability
L1 takes a feature vector x_t and outputs a probability. Above a threshold → candidate signal. The threshold is tuned per market cluster based on validation data.
Pipeline Expected Value
Expected return per candidate signal. Each layer filters, so fewer trades are taken but each one has higher expected value. The product of pass rates times conditional expected return determines overall system profitability.
Hands-On Code
Multi-Layer Pipeline Skeleton
class TradingPipeline:
"""Three-layer ML trading pipeline."""
def __init__(self, l1_model, l2_model, l3_model):
self.l1 = l1_model # Signal detection
self.l2 = l2_model # Entry filter
self.l3 = l3_model # Exit management
def evaluate_signal(self, features):
"""Run a candidate through all three layers."""
# Layer 1: Is there a signal?
l1_prob = self.l1.predict_proba(features)
if l1_prob < self.l1.threshold:
return None # No signal
# Layer 2: Should we enter?
l2_context = {
'l1_probability': l1_prob,
'spread': features['spread'],
'regime': features['regime'],
'recent_performance': self.get_recent_stats(),
}
l2_decision = self.l2.predict(l2_context)
if l2_decision == 'SKIP':
return None # Signal exists but timing is wrong
# Layer 3 activates after entry
return {
'action': 'ENTER',
'confidence': l1_prob,
'l3_params': self.l3.get_exit_params(features),
}
def manage_open_trade(self, trade, current_features):
"""L3 manages the trade after entry."""
exit_signal = self.l3.evaluate(trade, current_features)
if exit_signal['should_exit']:
return {'action': 'EXIT', 'reason': exit_signal['reason']}
return {'action': 'HOLD'}Each layer has a single responsibility. L1 finds opportunities. L2 decides timing. L3 manages the trade. This separation makes the system easier to improve, test, and debug.
Knowledge Check
Q1.Why does a multi-layer pipeline outperform a single model?
Q2.What's the main risk of a multi-layer architecture?
Assignment
Design a three-layer pipeline on paper. For each layer, specify: (1) what inputs it takes, (2) what output it produces, (3) what model type you'd use, and (4) how you'd validate it independently. Don't build it yet — just think through the architecture.