Architecture Overview¶
The Grid Trading Bot follows a modular, event-driven architecture with clear separation of concerns.
Package Layout¶
The project uses a src layout:
src/grid_trading_bot/
├── cli.py # Click CLI entry point
├── __main__.py # python -m support
├── core/
│ ├── bot_management/ # Bot lifecycle & orchestration
│ │ ├── grid_trading_bot.py # Main orchestrator
│ │ ├── event_bus.py # Pub/sub event system
│ │ ├── bot_controller.py # Runtime CLI commands
│ │ ├── health_check.py # System monitoring
│ │ └── notification_handler.py # Apprise alerts
│ ├── grid_management/ # Grid computation & state
│ │ ├── grid_manager.py # Level calculation
│ │ └── grid_level.py # Level state machine
│ ├── order_handling/ # Order lifecycle
│ │ ├── order_manager.py # Order orchestration
│ │ ├── balance_tracker.py # Fiat/crypto balances
│ │ ├── order_book.py # Order-to-grid mapping
│ │ └── execution_strategy/ # Backtest vs live execution
│ ├── persistence/ # State persistence (live mode)
│ │ ├── state_persistence_service.py # Event-driven checkpoints
│ │ ├── state_recovery_service.py # Merge recovery on restart
│ │ ├── sqlite_state_repository.py # SQLite backend
│ │ └── serializers.py # Model serialization
│ ├── services/ # Exchange abstraction
│ │ ├── backtest_exchange_service.py
│ │ └── live_exchange_service.py
│ └── validation/ # Order validation
├── strategies/ # Trading strategies
│ ├── grid_trading_strategy.py # Main strategy logic
│ ├── trading_performance_analyzer.py
│ └── plotter.py # Plotly visualization
├── config/ # Configuration management
│ ├── config_manager.py
│ ├── config_validator.py
│ └── trading_mode.py
└── utils/ # Logging, I/O helpers
Module Dependencies¶
flowchart TD
CLI["cli.py"] --> Bot["GridTradingBot"]
Bot --> Strategy["GridTradingStrategy"]
Bot --> EventBus["EventBus"]
Bot --> HealthCheck["HealthCheck"]
Bot --> BotController["BotController"]
Bot --> Notification["NotificationHandler"]
Strategy --> OrderManager["OrderManager"]
Strategy --> GridManager["GridManager"]
OrderManager --> BalanceTracker["BalanceTracker"]
OrderManager --> OrderBook["OrderBook"]
OrderManager --> ExecutionStrategy["ExecutionStrategy"]
ExecutionStrategy --> ExchangeService["ExchangeService"]
OrderManager --> OrderValidator["OrderValidator"]
GridManager --> GridLevel["GridLevel"]
Bot --> PersistenceService["StatePersistenceService"]
Bot --> RecoveryService["StateRecoveryService"]
PersistenceService --> StateRepository["SQLiteStateRepository"]
RecoveryService --> StateRepository
Design Patterns¶
Factory Pattern¶
Two factories select implementations based on the configured TradingMode:
ExchangeServiceFactory— ReturnsBacktestExchangeServiceorLiveExchangeServiceOrderExecutionStrategyFactory— Returns instant (backtest) or retrying (live) execution
Event Bus¶
Decoupled communication via a publish/subscribe system. Components subscribe to events rather than calling each other directly.
| Event | Published When | Typical Subscribers |
|---|---|---|
ORDER_FILLED |
An order is fully executed | OrderManager, BalanceTracker, StatePersistenceService |
ORDER_CANCELLED |
An order is cancelled | OrderManager, StatePersistenceService |
START_BOT |
Bot initialization complete | BotController |
STOP_BOT |
Shutdown requested | All components |
INITIAL_PURCHASE_DONE |
Initial crypto purchase completed | StatePersistenceService |
GRID_ORDERS_INITIALIZED |
Grid orders placed for the first time | StatePersistenceService |
State Machine¶
Each GridLevel transitions through GridCycleState as orders are placed and filled:
stateDiagram-v2
[*] --> READY_TO_BUY_OR_SELL
READY_TO_BUY_OR_SELL --> WAITING_FOR_BUY_FILL: Place buy
READY_TO_BUY_OR_SELL --> WAITING_FOR_SELL_FILL: Place sell
READY_TO_BUY --> WAITING_FOR_BUY_FILL: Place buy
WAITING_FOR_BUY_FILL --> READY_TO_SELL: Buy filled
READY_TO_SELL --> WAITING_FOR_SELL_FILL: Place sell
WAITING_FOR_SELL_FILL --> READY_TO_BUY: Sell filled
Strategy Pattern¶
TradingStrategyInterface defines the ABC. GridTradingStrategy implements it with two execution modes:
- Backtest mode — Iterates over OHLCV rows synchronously
- Live/Paper mode — Consumes a WebSocket price stream asynchronously
The strategy handles:
- Initial purchase (50% allocation of initial balance)
- Grid order initialization across computed levels
- Order fill handling (buy fill → place sell above, sell fill → place buy below)
- Take-profit and stop-loss monitoring
Trading Modes¶
| Mode | Exchange Service | Execution Strategy | Additional Tasks |
|---|---|---|---|
backtest |
BacktestExchangeService (CSV/CCXT OHLCV) |
Instant fill | None |
paper_trading |
LiveExchangeService (sandbox APIs) |
Retry with backoff | BotController, HealthCheck |
live |
LiveExchangeService (production APIs) |
Retry with backoff | BotController, HealthCheck, StatePersistence, ReconciliationService |
In live and paper modes, the bot runs three concurrent async tasks:
- Trading strategy — Price consumption and order management
- BotController — Runtime CLI commands for status and control
- HealthCheck — System resource monitoring (CPU, memory)
State Persistence (Live Mode Only)¶
In live trading mode, the bot persists its state to a SQLite database so it can recover from crashes or restarts without losing order history, grid states, or balance tracking.
How It Works¶
- Checkpoint strategy: Event-driven — a full snapshot is written after every
ORDER_FILLED,ORDER_CANCELLED,INITIAL_PURCHASE_DONE, andGRID_ORDERS_INITIALIZEDevent - Database: SQLite with WAL (Write-Ahead Logging) mode for crash safety
- DB path:
data/{BASE}_{QUOTE}/state_{config_hash[:8]}.db(auto-derived, or explicit viapersistence.db_pathin config)
Recovery on Restart¶
When the bot starts in live mode with an existing state DB:
- Config compatibility — Compares config hash; if grid configuration changed, clears DB and starts fresh
- Grid level restoration — Overlays saved states and paired-level references onto freshly computed grid levels
- Order restoration — Reconstructs Order objects from DB, repopulates the OrderBook
- Exchange reconciliation — For each locally-open order, fetches current status from exchange:
- Filled while bot was down → updates status locally
- Canceled on exchange → releases reserved funds
- Not found → marks as ghost, releases funds
- Orphan orders on exchange (not in local book) → logged as warnings, not auto-adopted
- Balance restoration — Exchange balance is authoritative; DB reserved amounts are overlaid
Configuration¶
Both fields are optional. Persistence is enabled by default in live mode. The db_path defaults to data/{BASE}_{QUOTE}/state_{hash}.db where {hash} is derived from the grid configuration, ensuring different grid configs get separate databases even for the same trading pair