How a Typical Open-Source Robot Works Inside: Architecture of a Simple Strategy
Three months ago, I compared open-source frameworks for MOEX. Figured out what to choose. But the question remained: how does it all work inside?
You can read the docs. You can study the API. But real understanding comes only when you open the code and see the architecture.
So today isnβt about choosing a platform. Itβs about what happens under the hood.
I analyzed the architecture of four popular open-source robots: Freqtrade, NautilusTrader, Hummingbot, and the microservices-based MBATS.
Conclusion: despite different languages and goals, patterns repeat. If you understand them, you can design your own system right from the start.
Layered Architecture: The Foundation
Most trading robots follow a 5-layer architecture:
Layer 5: Communication Layer <- Telegram, Web UI, API
Layer 4: Strategy Layer <- Trading logic
Layer 3: Execution & Risk <- Orders, risk management
Layer 2: Data Processing <- Indicators, normalization
Layer 1: Data Ingestion <- Exchange connections
Layer 1: Data Ingestion
Task: Get data from the exchange and deliver it to the system.
Freqtrade uses ccxt to support 100+ exchanges without writing separate connectors. NautilusTrader has its core in Rust with streaming up to 5 million rows per second.
Takeaways: Use adapters, unify interfaces, separate data retrieval from processing.
Layer 2: Data Processing
Task: Transform raw prices into indicators, ML features, signals.
NautilusTrader writes all indicators in Rust with bounded memory. FreqAI integrates ML (LightGBM, PyTorch, Reinforcement Learning) directly into Freqtrade.
Takeaways: Separate feature generation from inference, cache indicator calculations, use bounded buffers.
Layer 3: Execution & Risk Management
Task: Take a βbuyβ decision and turn it into a real order with risk controls.
Freqtrade includes dynamic position sizing and overtrading protection. Microservices architectures use Smart Order Routing (SOR) as a separate service.
Layer 4: Strategy Layer
Task: Determine when to buy and sell.
Freqtrade completely separates strategy from execution. NautilusTrader uses the Actor Model for event-driven strategies with microsecond reactions.
Layer 5: Communication & Monitoring
Freqtrade has built-in Telegram bot, REST API, and Web UI. Professional systems export metrics to Prometheus and visualize in Grafana.
Design Patterns for Trading Robots
1. Event Sourcing
Saves every state change as an event. Crucial for auditing, debugging, and regulatory compliance.
2. CQRS (Command Query Responsibility Segregation)
Separates reads from writes. The Event Store handles writes; a separate database with pre-computed aggregates handles queries.
3. Microservices Architecture
MBATS splits the system into independent services communicating via Kafka/RabbitMQ. Each service scales independently. Different languages for different tasks.
4. Actor Model
NautilusTrader and Hummingbot use it. Each actor has independent state, communicates via messages. No shared state means no race conditions.
Checklist: Designing Your Own Robot
- Start with a monolith β donβt jump to microservices prematurely
- Separate layers from day one β even in a monolith
- Design for testing β dependency injection, mocks, abstractions
- Add observability from day one β logs, metrics, tracing
- Plan persistence β save all orders, positions, settings, events
- Switch to microservices only when: >100 instruments, HFT, team >3 developers
Common Mistakes
- Everything in one file β impossible to test, reuse, or maintain
- No exchange abstractions β adding a second exchange means changing code in 50 places
- No logging or metrics β you wonβt understand why the robot traded at 3 AM
- Synchronous code β use async (aiohttp, not requests) for exchange APIs
- Ignoring backpressure β use bounded queues to prevent memory growth
Conclusions
Key principles:
- Separate layers β data, processing, strategy, execution, communication
- Use adapters β donβt write exchange logic in strategies
- Design for testing β dependency injection
- Add observability β logs, metrics, tracing
- Start with a monolith β donβt over-engineer prematurely
Architecture determines how far youβll go. Spaghetti code works for a month. Proper architecture β for years.
Useful links:
Discussion
Join the discussion in our Telegram chat!