How do you run multiple strategies on MetaTrader 5 when the platform assumes one Expert Advisor equals one strategy? What happens to your open positions when your VPS crashes at 3 AM? Can you actually build institutional-grade portfolio management without paying $50k for enterprise platforms?
If you've tried building algorithmic trading portfolios on MetaTrader 5, you've hit these walls. The platform wasn't designed for portfolio trading. There's minimal documentation on solving multi-strategy orchestration. And every "solution" you find online is either a $10k course or a fragmented GitHub repo that breaks on the first real trade.
Here's what I learned after years of building trading systems in production: the problem isn't finding the perfect strategy. It's building the infrastructure to run multiple strategies as a unified portfolio. That's why I built Horizon5 as a portfolio-first framework for MetaTrader 5.
Table of Contents:
- The MetaTrader Problem: One EA, One Strategy
- Building a Multi-Strategy Trading Framework
- Order Persistence: Surviving Crashes
- Multi-Level Quality Metrics
- Time-Based Event System
- Multi-Strategy Trading Framework in Practice
- What a Multi-Strategy Trading Framework Enables
The MetaTrader Problem: One EA, One Strategy
MetaTrader 5 was designed with a simple mental model: one Expert Advisor trades one symbol with one strategy. That works fine if you're running a single system.
But here's what happens when you try to scale:
- No centralized capital allocation: Each EA calculates lot sizes independently without knowing about other running strategies
- Scattered risk management: Risk controls happen per-EA, not at portfolio level
- No unified metrics: You're tracking performance across multiple disconnected systems
- Manual coordination required: Rebalancing, weight allocation, correlation analysis are all manual processes open to human error
The typical workaround is running multiple MetaTrader 5 EAs simultaneously. One per strategy. But then you face coordination problems.
I worked with traders who asked specific questions: "How do we deactivate a strategy mid-period and see the impact?" "How do we adjust weights dynamically across strategies?" "How do we visualize total portfolio exposure?"
These questions don't have good answers in the traditional MetaTrader model. You end up managing everything manually with spreadsheets and hoping nothing breaks.
Building a Multi-Strategy Trading Framework
Horizon5 inverts the traditional approach with a portfolio-first algorithmic trading architecture. Instead of strategy-first thinking (build a strategy, then figure out how to run it), it starts from portfolio-first thinking: how do multiple strategies work together?
The Hierarchy: Portfolio, Assets, Strategies
The architecture uses three levels:
// Portfolio level: manages all assets
SEAsset *assets[] = {
new GoldAsset(),
new EURUSDAsset()
};
// Each asset contains its strategies
class GoldAsset : public SEAsset {
SEStrategy *strategies[];
GoldAsset() {
ArrayResize(strategies, 1);
strategies[0] = new ATRBreakoutStrategy("XAUUSD");
}
};Portfolio manages capital allocation across all assets. Assets group strategies that trade the same symbol. Strategies contain the actual trading logic.
This isn't arbitrary hierarchy. It reflects how portfolio risk actually works.
A strategy generates signals. But the asset layer controls how much capital that strategy can use. And the portfolio layer determines how capital distributes across assets based on correlations, volatility, and overall exposure. This multi-symbol expert advisor approach lets you manage XAUUSD, EURUSD, and any other symbols from a single unified system.
Why This Structure Matters
When you want to add a new strategy, you don't modify the core framework. You create one file, define your logic, and register it with an asset.
The framework handles:
- Capital distribution (currently equal-weight, dynamic allocation on the roadmap)
- Event propagation to all strategies
- Statistics collection at every level
- Order tracking and persistence
This separation means strategies focus purely on signal generation. They don't implement risk management, position sizing, or persistence. That's handled by the framework services.
Order Persistence: Surviving Crashes
Here's a problem most retail traders don't think about until it bites them: what happens when MetaTrader crashes?
Your VPS reboots at 3 AM. MetaTrader restarts. Your EA initializes fresh with no memory of previous positions. But those positions are still in the market.
Now you have orphaned positions your code doesn't know about. Exposure you can't control. Stop losses that might not trigger because your EA doesn't know they exist.
This is a serious problem for live trading. Proper trading strategy management requires knowing the state of every position at all times. The Horizon5 framework solves it with JSON-based order persistence.
The State Machine
Every order in the framework goes through a defined lifecycle:
enum ENUM_ORDER_STATUSES {
ORDER_STATUS_QUEUED, // Market closed, waiting to send
ORDER_STATUS_PENDING, // Limit order placed, not filled
ORDER_STATUS_OPEN, // Position active in market
ORDER_STATUS_CLOSING, // Close request sent
ORDER_STATUS_CLOSED, // Position closed with P/L recorded
ORDER_STATUS_CANCELLED // Order cancelled before execution
};The QUEUED state is particularly useful. If your strategy generates a signal when the market is closed (weekends, holidays), the order queues and executes automatically when the market reopens. No manual intervention needed.
JSON Serialization for Recovery
When an order opens, the framework immediately serializes it to disk:
bool SaveOrderToJson(EOrder &order) {
string filePath = GetOrderFilePath(order.GetSource(), order.GetId());
string jsonData = SerializeOrder(order);
int fileHandle = FileOpen(filePath, FILE_WRITE|FILE_TXT);
if(fileHandle != INVALID_HANDLE) {
FileWriteString(fileHandle, jsonData);
FileClose(fileHandle);
return true;
}
return false;
}On initialization, the framework scans for existing order files and restores them:
int LoadOrdersFromJson(string strategyName, EOrder &restoredOrders[]) {
string searchPattern = strategyName + "_*.json";
// Scan directory, parse JSON files, restore order objects
// Returns count of restored orders
}When your EA restarts after a crash, it automatically picks up where it left off. Open positions are tracked. Stop losses are monitored. You don't lose traceability.
This isn't optional for serious live trading. Without persistence, every restart is a potential disaster.
Multi-Level Quality Metrics
Backtesting typically optimizes a single strategy for maximum profit or Sharpe ratio. That's not enough for portfolio management.
The framework implements quality metrics at three levels because optimization requirements differ at each level.
Strategy-Level Optimization
At the strategy level, you optimize for signal quality:
// Statistics service calculates real-time metrics
double sharpeRatio = statistics.GetSharpeRatio();
double maxDrawdown = statistics.GetMaxDrawdownPercent();
double rSquared = statistics.GetRSquared();
double recoveryFactor = statistics.GetRecoveryFactor();The framework supports 8 different optimization formulas:
- Performance: Raw profit optimization
- Drawdown: Minimize maximum drawdown
- Risk/Reward: Balance between profit and risk
- Sharpe Ratio: Risk-adjusted returns
- Win Rate: Signal accuracy
- R-Squared: Equity curve linearity
- Trade Count: Ensure statistical significance
- Layer Distribution: For recovery-based strategies
You configure quality thresholds and the framework scores each backtest run:
input ENUM_QUALITY_FORMULA QualityFormula = QUALITY_FORMULA_SHARPE_RATIO;
input double QualityThresholdMin = 0.5;
input double QualityThresholdMax = 3.0;This enables proper multi-objective optimization in MetaTrader's Strategy Tester.
Asset-Level Risk Management
After optimizing individual strategies, you need to optimize at the asset level.
How much drawdown can this asset tolerate? What's the maximum position size across all strategies trading this symbol? How do strategies on this asset correlate with each other?
These questions are different from strategy optimization. A strategy might have excellent signals but inappropriate position sizing for your portfolio. The asset layer handles that calibration.
Portfolio-Level Evaluation
Finally, portfolio-level metrics evaluate how everything works together.
This is where correlation analysis matters. Two profitable strategies that correlate 0.9 with each other don't provide diversification. You'd be better off with one profitable strategy and one lower-profit strategy that's uncorrelated.
The framework architecture supports this layered optimization approach. Strategy first, then asset configuration, then portfolio allocation.
Time-Based Event System
Trading logic often depends on time granularity. Some strategies act on every tick. Others only check conditions at the start of each hour or day.
The framework provides granular time-based events:
virtual void OnTick() {}
virtual void OnStartMinute() {}
virtual void OnStartHour() {}
virtual void OnStartDay() {}
virtual void OnStartWeek() {}
virtual void OnStartMonth() {}Events propagate from the main EA through assets to all strategies:
void OnTick() {
// Propagate to all assets
for(int i = 0; i < ArraySize(assets); i++) {
assets[i].OnTick();
}
}
// Inside asset
void OnTick() {
// Propagate to all strategies
for(int i = 0; i < ArraySize(strategies); i++) {
strategies[i].OnTick();
}
}A breakout strategy might only check for signals at OnStartDay() when yesterday's high/low are defined. A scalping strategy might need OnTick() for every price update. A rebalancing algorithm might run at OnStartMonth().
This decouples timing logic from trading logic. Strategies declare what events they care about. The framework handles the timing infrastructure.
Multi-Strategy Trading Framework in Practice
Here's how you'd implement a simple ATR breakout strategy in this framework:
class ATRBreakoutStrategy : public SEStrategy {
private:
int atrHandle;
double atrMultiplier;
public:
ATRBreakoutStrategy(string symbol) : SEStrategy(symbol) {
atrHandle = iATR(symbol, PERIOD_D1, 14);
atrMultiplier = 2.0;
}
void OnStartDay() {
// Check for breakout condition at day start
double atr[];
CopyBuffer(atrHandle, 0, 1, 1, atr);
double previousHigh = iHigh(symbol, PERIOD_D1, 1);
double currentPrice = SymbolInfoDouble(symbol, SYMBOL_BID);
if(currentPrice > previousHigh + (atr[0] * atrMultiplier)) {
// Generate buy signal
OpenOrder(ORDER_TYPE_BUY, CalculateLotSize());
}
}
};The strategy doesn't handle:
- Position sizing beyond its allocated capital
- Persistence of orders across restarts
- Statistics calculation
- Time event management
All of that is framework responsibility. The strategy focuses purely on its trading logic.
Adding this strategy to the portfolio:
class GoldAsset : public SEAsset {
GoldAsset() : SEAsset("XAUUSD") {
ArrayResize(strategies, 1);
strategies[0] = new ATRBreakoutStrategy("XAUUSD");
}
};
// In main EA
SEAsset *assets[] = { new GoldAsset() };One file for the strategy. One file for the asset. Register in main EA. Capital allocation handles automatically.
What a Multi-Strategy Trading Framework Enables
Building this framework changed how I think about algorithmic trading.
Instead of searching for the perfect strategy, I focus on strategy diversification. When one strategy struggles due to regime changes, others compensate.
Instead of manual coordination across multiple EAs, I have centralized portfolio management. Capital allocation, risk controls, and metrics happen at the framework level.
Instead of hoping nothing breaks during live trading, I have order persistence. Crashes don't mean lost traceability.
The framework is open source and available on GitHub. It's the infrastructure I wish existed when I was managing multiple strategies with spreadsheets and duct tape.
Institutions don't run one strategy. They run portfolios. And now, with the right framework, individual traders can think the same way.
If you're building portfolio-based systems on MetaTrader 5, this solves the infrastructure problems so you can focus on strategy development rather than framework engineering.