The Problem That Started It

Trading gold (XAUUSD) manually had a consistent failure mode that I couldn’t solve with discipline alone: emotional decision-making at exactly the wrong moment.

Smart Money Concepts (SMC) is a methodology for reading institutional order flow in financial markets. It identifies where large players (often called “smart money”) have placed their orders by analysing price action around specific zones — order blocks, fair value gaps, and liquidity pools. The signals are objective. The execution is where humans fall apart.

When a trade is down 3% and your manual stop-loss is at 4%, the emotional pressure to widen the stop is nearly irresistible. I needed a system that would execute what the charts said, regardless of how I felt.

The Core Challenge: Real-Time Market Data Synchronisation

The fundamental difficulty with automated trading against MT5 (MetaTrader 5) isn’t placing orders — it’s receiving reliable market data in real-time. MT5’s Python API has unpredictable latency spikes during high-volatility periods (exactly when you most need reliable data). A trade signal could arrive during a spike, causing the system to either miss the entry entirely or place it at an unfavourable price.

This isn’t a niche problem. Any system consuming real-time data from an external API faces the same challenge: what do you do when the data feed becomes unreliable?

Architecture Decisions

The system has four main components, each isolated so failure in one doesn’t cascade to others.

MT5 bridge — A thin layer that translates between MT5’s API surface and the system’s internal representation. MT5 is a Windows-native platform with its own threading model. Wrapping it cleanly meant keeping this layer as thin as possible — its only job is to surface price data and accept order instructions.

FastAPI backend — This is where signals are generated and evaluated. FastAPI’s native async support was critical here. Handling multiple concurrent WebSocket connections to MT5, managing a queue of pending signals, and serving a web dashboard simultaneously required genuine concurrency, not threading workarounds.

WebSocket feed — The dashboard connects via WebSocket to receive real-time position updates, trade notifications, and system status. This keeps the UI responsive without polling.

Circuit breaker layer — The most important architectural decision. Instead of relying on MT5’s API directly for execution, every trade passes through a circuit breaker that monitors MT5’s response times in real-time. When latency exceeds 2x the rolling average, the breaker opens and queues incoming signals. Once MT5 recovers (detected by successful ping responses), the breaker half-opens and gradually reintroduces live trading.

The Circuit Breaker: Why It Matters More Than the Trading Strategy

Most automated trading discussions focus on strategy — which indicators to use, how to identify entry points. In my experience after six months of production running, the circuit breaker matters more.

Here’s why: a brilliant strategy that misses orders during volatility events will consistently underperform a mediocre strategy that executes reliably. The circuit breaker turned a system with ~40% missed trades during news events into one with 94% execution reliability during the same periods.

The implementation tracks three metrics in a sliding window: response latency, error rate, and consecutive failures. When any threshold is breached, the breaker opens. What makes it production-grade rather than a simple flag is the half-open state — a single successful request doesn’t immediately restore full trading. The breaker requires N consecutive successes before fully closing, which prevents a single ping success from triggering a flood of orders into a still-recovering MT5 connection.

Results After Six Months

The system has been running live since mid-2025. The results that matter:

  • 73% win rate — up from an estimated ~57% for my manual trading over the same prior period
  • Sub-50ms trade execution when the market is stable
  • Maximum observed drawdown: 4.2% — the circuit breaker has never allowed a loss beyond the defined maximum
  • 1,200+ signals processed daily with no manual intervention

The Telegram integration deserves specific mention. Every trade generates an instant notification with entry price, position size, and stop-loss level. Every circuit breaker state change generates an alert. I can go days without opening the dashboard — the system tells me when something needs attention.

What I’d Do Differently

The main thing I’d change is the backtesting infrastructure. I built the strategy logic without adequate historical testing infrastructure in place, which meant validating new strategy variants was slower than it should have been. By the time I added proper backtesting, I’d already been running live for two months.

The lesson: build the backtesting framework before you start live trading, even if you think you don’t need it. You’ll need it.

The second thing is that the web dashboard is over-engineered for what it actually needs to display. I spent time building animated charts and real-time P&L visualisations that I never actually look at — I care about the Telegram alerts. Simpler dashboard, more work on the alerting layer.

The SMC Signal Detection Logic

I won’t share implementation details, but the high-level approach to signal detection is worth discussing because it directly impacts win rate.

SMC identifies trade setups around specific price zones. The key insight is that these zones aren’t arbitrary — they’re where institutional order flow has previously created measurable price reactions. When price returns to such a zone, the probability of another reaction is meaningfully higher than random.

The system doesn’t trade every signal. It applies a confluence filter: a valid signal requires agreement across multiple timeframe analysis, a favourable risk-reward ratio (minimum 2:1), and confirmation from the circuit breaker that execution conditions are stable.

This filtering reduces total trade count by approximately 40%, but improves win rate by 16 percentage points. Fewer trades, better quality.

What the Future Looks Like

I’m currently working on extending the signal detection to include volume profile analysis — identifying institutional volume clusters that add a further confluence filter to entries. Early testing suggests another 3-5 percentage points of win rate improvement is achievable, though with a further reduction in trade frequency.

The bigger challenge is that this approach requires significant capital to execute properly at scale. Position sizing that makes sense for a single retail account creates different risk profiles at institutional sizes. That’s a different problem entirely.