153 lines
No EOL
4.6 KiB
Markdown
153 lines
No EOL
4.6 KiB
Markdown
# Migration Guide: Modular Architecture
|
|
|
|
This guide explains how to migrate from the current monolithic structure to the new modular architecture.
|
|
|
|
## Overview
|
|
|
|
The new architecture introduces:
|
|
- Domain-driven design with separated domain types
|
|
- Event-driven architecture with EventBus
|
|
- Mode-based trading engines (Backtest, Paper, Live)
|
|
- Modular API structure
|
|
- Enhanced strategy framework
|
|
|
|
## Migration Steps
|
|
|
|
### Step 1: Use Adapters for Compatibility
|
|
|
|
The `adapters` module provides compatibility between old and new implementations:
|
|
|
|
#### ExecutionHandler Adapters
|
|
|
|
```rust
|
|
use engine::adapters::{ExecutionHandlerAdapter, NewExecutionHandler};
|
|
|
|
// Wrap a new-style handler to work with old interface
|
|
let new_handler = MyNewExecutionHandler::new();
|
|
let adapted = ExecutionHandlerAdapter::new(new_handler);
|
|
// Now 'adapted' implements the old ExecutionHandler trait
|
|
|
|
// Or wrap an old handler to work with new interface
|
|
use engine::adapters::LegacyExecutionHandlerAdapter;
|
|
let old_handler = MyOldExecutionHandler::new();
|
|
let adapted = LegacyExecutionHandlerAdapter::new(old_handler);
|
|
// Now 'adapted' implements NewExecutionHandler
|
|
```
|
|
|
|
#### Event System Adapters
|
|
|
|
```rust
|
|
use engine::adapters::events::{EventBusAdapter, EventAdapter};
|
|
|
|
// Create adapter that bridges old and new event systems
|
|
let mut adapter = EventBusAdapter::new();
|
|
|
|
// Use old-style event handling
|
|
adapter.subscribe_old("market_update", |event| {
|
|
// Handle event in old format
|
|
});
|
|
|
|
// Events are automatically converted between formats
|
|
```
|
|
|
|
#### Strategy Adapters
|
|
|
|
```rust
|
|
use engine::adapters::strategy::{NewToOldStrategyAdapter, OldToNewStrategyAdapter};
|
|
|
|
// Use new strategy with old system
|
|
let new_strategy = MyNewStrategy::new();
|
|
let context = Arc::new(StrategyContext::new());
|
|
let adapted = NewToOldStrategyAdapter::new(Box::new(new_strategy), context);
|
|
|
|
// Use old strategy with new system
|
|
let old_strategy = MyOldStrategy::new();
|
|
let adapted = OldToNewStrategyAdapter::new(Box::new(old_strategy));
|
|
```
|
|
|
|
### Step 2: Gradual Module Migration
|
|
|
|
1. **Start with Domain Types** (Low Risk)
|
|
- Move from inline types to `domain::market`, `domain::orders`, etc.
|
|
- These are mostly data structures with minimal behavior
|
|
|
|
2. **Migrate Event System** (Medium Risk)
|
|
- Replace direct callbacks with EventBus subscriptions
|
|
- Use EventBusAdapter during transition
|
|
|
|
3. **Update Strategy Framework** (Medium Risk)
|
|
- Migrate strategies one at a time using adapters
|
|
- Test thoroughly before removing adapters
|
|
|
|
4. **Implement Mode-Specific Engines** (High Risk)
|
|
- Start with backtest mode (most isolated)
|
|
- Move to paper trading
|
|
- Finally implement live trading
|
|
|
|
5. **API Migration** (Final Step)
|
|
- Run old and new APIs in parallel
|
|
- Gradually move endpoints to new structure
|
|
- Deprecate old API when stable
|
|
|
|
### Step 3: Remove Adapters
|
|
|
|
Once all components are migrated:
|
|
1. Remove adapter usage
|
|
2. Delete old implementations
|
|
3. Remove adapter modules
|
|
|
|
## Testing Strategy
|
|
|
|
1. **Unit Tests**: Test adapters ensure compatibility
|
|
2. **Integration Tests**: Verify old and new systems work together
|
|
3. **Regression Tests**: Ensure no functionality is lost
|
|
4. **Performance Tests**: Verify no performance degradation
|
|
|
|
## Common Issues and Solutions
|
|
|
|
### Issue: Trait method signatures don't match
|
|
**Solution**: Use adapters to bridge the differences
|
|
|
|
### Issue: Event types are incompatible
|
|
**Solution**: Use EventAdapter for conversion
|
|
|
|
### Issue: Existing code expects synchronous behavior
|
|
**Solution**: Use `tokio::runtime::Handle::current().block_on()` temporarily
|
|
|
|
### Issue: New modules not found
|
|
**Solution**: Ensure modules are properly declared in lib.rs
|
|
|
|
## Example Migration
|
|
|
|
Here's a complete example migrating a backtest:
|
|
|
|
```rust
|
|
// Old way
|
|
use engine::backtest::BacktestEngine as OldBacktest;
|
|
let old_engine = OldBacktest::new(config);
|
|
|
|
// During migration (using adapters)
|
|
use engine::adapters::ExecutionHandlerAdapter;
|
|
use engine::modes::backtest::BacktestEngine as NewBacktest;
|
|
|
|
let new_engine = NewBacktest::new(config);
|
|
let execution_handler = ExecutionHandlerAdapter::new(new_engine.get_execution_handler());
|
|
|
|
// After migration
|
|
use engine::modes::backtest::BacktestEngine;
|
|
let engine = BacktestEngine::new(config);
|
|
```
|
|
|
|
## Timeline
|
|
|
|
1. **Week 1-2**: Implement and test adapters
|
|
2. **Week 3-4**: Migrate domain types and events
|
|
3. **Week 5-6**: Migrate strategies and modes
|
|
4. **Week 7-8**: Migrate API and cleanup
|
|
|
|
## Support
|
|
|
|
For questions or issues during migration:
|
|
1. Check adapter documentation
|
|
2. Review test examples
|
|
3. Consult team lead for architectural decisions |