205 lines
6.9 KiB
Markdown
205 lines
6.9 KiB
Markdown
# ADR-003: Dash Web Framework for Visualization
|
|
|
|
## Status
|
|
Accepted
|
|
|
|
## Context
|
|
The orderflow backtest system requires a user interface for visualizing OHLC candlestick charts, volume data, orderbook depth, and derived metrics. Key requirements include:
|
|
|
|
- Real-time chart updates with minimal latency
|
|
- Professional financial data visualization capabilities
|
|
- Support for multiple chart types (candlesticks, bars, line charts)
|
|
- Interactive features (zooming, panning, hover details)
|
|
- Dark theme suitable for trading applications
|
|
- Python-native solution to avoid JavaScript development
|
|
|
|
## Decision
|
|
We will use Dash (by Plotly) as the web framework for building the visualization frontend, with Plotly.js for chart rendering.
|
|
|
|
## Consequences
|
|
|
|
### Positive
|
|
- **Python-native**: No JavaScript development required
|
|
- **Plotly integration**: Best-in-class financial charting capabilities
|
|
- **Reactive architecture**: Automatic UI updates via callback system
|
|
- **Professional appearance**: High-quality charts suitable for trading applications
|
|
- **Interactive features**: Built-in zooming, panning, hover tooltips
|
|
- **Responsive design**: Bootstrap integration for modern layouts
|
|
- **Development speed**: Rapid prototyping and iteration
|
|
- **WebGL acceleration**: Smooth performance for large datasets
|
|
|
|
### Negative
|
|
- **Performance overhead**: Heavier than custom JavaScript solutions
|
|
- **Limited customization**: Constrained by Dash component ecosystem
|
|
- **Single-page limitation**: Not suitable for complex multi-page applications
|
|
- **Memory usage**: Can be heavy for resource-constrained environments
|
|
- **Learning curve**: Callback patterns require understanding of reactive programming
|
|
|
|
## Implementation Details
|
|
|
|
### Application Structure
|
|
```python
|
|
# Main application with Bootstrap theme
|
|
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.FLATLY])
|
|
|
|
# Responsive layout with 9:3 ratio for charts:depth
|
|
app.layout = dbc.Container([
|
|
dbc.Row([
|
|
dbc.Col([ # OHLC + Volume + Metrics
|
|
dcc.Graph(id='ohlc-chart', style={'height': '100vh'})
|
|
], width=9),
|
|
dbc.Col([ # Orderbook Depth
|
|
dcc.Graph(id='depth-chart', style={'height': '100vh'})
|
|
], width=3)
|
|
]),
|
|
dcc.Interval(id='interval-update', interval=500, n_intervals=0)
|
|
])
|
|
```
|
|
|
|
### Chart Architecture
|
|
```python
|
|
# Multi-subplot chart with shared x-axis
|
|
fig = make_subplots(
|
|
rows=3, cols=1,
|
|
row_heights=[0.6, 0.2, 0.2], # OHLC, Volume, Metrics
|
|
vertical_spacing=0.02,
|
|
shared_xaxes=True,
|
|
subplot_titles=['Price', 'Volume', 'OBI Metrics']
|
|
)
|
|
|
|
# Candlestick chart with dark theme
|
|
fig.add_trace(go.Candlestick(
|
|
x=timestamps, open=opens, high=highs, low=lows, close=closes,
|
|
increasing_line_color='#00ff00', decreasing_line_color='#ff0000'
|
|
), row=1, col=1)
|
|
```
|
|
|
|
### Real-time Updates
|
|
```python
|
|
@app.callback(
|
|
[Output('ohlc-chart', 'figure'), Output('depth-chart', 'figure')],
|
|
[Input('interval-update', 'n_intervals')]
|
|
)
|
|
def update_charts(n_intervals):
|
|
# Read data from JSON files with error handling
|
|
# Build and return updated figures
|
|
return ohlc_fig, depth_fig
|
|
```
|
|
|
|
## Performance Characteristics
|
|
|
|
### Update Latency
|
|
- **Polling interval**: 500ms for near real-time updates
|
|
- **Chart render time**: 50-200ms depending on data size
|
|
- **Memory usage**: ~100MB for typical chart configurations
|
|
- **Browser requirements**: Modern browser with WebGL support
|
|
|
|
### Scalability Limits
|
|
- **Data points**: Up to 10,000 candlesticks without performance issues
|
|
- **Update frequency**: Optimal at 1-2 Hz, maximum ~10 Hz
|
|
- **Concurrent users**: Single user design (development server)
|
|
- **Memory growth**: Linear with data history size
|
|
|
|
## Alternatives Considered
|
|
|
|
### Streamlit
|
|
- **Rejected**: Less interactive, slower updates, limited charting
|
|
- **Pros**: Simpler programming model, good for prototypes
|
|
- **Cons**: Poor real-time performance, limited financial chart types
|
|
|
|
### Flask + Custom JavaScript
|
|
- **Rejected**: Requires JavaScript development, more complex
|
|
- **Pros**: Complete control, potentially better performance
|
|
- **Cons**: Significant development overhead, maintenance burden
|
|
|
|
### Jupyter Notebooks
|
|
- **Rejected**: Not suitable for production deployment
|
|
- **Pros**: Great for exploration and analysis
|
|
- **Cons**: No real-time updates, not web-deployable
|
|
|
|
### Bokeh
|
|
- **Rejected**: Less mature ecosystem, fewer financial chart types
|
|
- **Pros**: Good performance, Python-native
|
|
- **Cons**: Smaller community, limited examples for financial data
|
|
|
|
### Custom React Application
|
|
- **Rejected**: Requires separate frontend team, complex deployment
|
|
- **Pros**: Maximum flexibility, best performance potential
|
|
- **Cons**: High development cost, maintenance overhead
|
|
|
|
### Desktop GUI (Tkinter/PyQt)
|
|
- **Rejected**: Not web-accessible, limited styling options
|
|
- **Pros**: No browser dependency, good performance
|
|
- **Cons**: Deployment complexity, poor mobile support
|
|
|
|
## Configuration Options
|
|
|
|
### Theme and Styling
|
|
```python
|
|
# Dark theme configuration
|
|
dark_theme = {
|
|
'plot_bgcolor': '#000000',
|
|
'paper_bgcolor': '#000000',
|
|
'font_color': '#ffffff',
|
|
'grid_color': '#333333'
|
|
}
|
|
```
|
|
|
|
### Chart Types
|
|
- **Candlestick charts**: OHLC price data with volume
|
|
- **Bar charts**: Volume and metrics visualization
|
|
- **Line charts**: Cumulative depth and trend analysis
|
|
- **Scatter plots**: Trade-by-trade analysis (future)
|
|
|
|
### Interactive Features
|
|
- **Zoom and pan**: Time-based navigation
|
|
- **Hover tooltips**: Detailed data on mouse over
|
|
- **Crosshairs**: Precise value reading
|
|
- **Range selector**: Quick time period selection
|
|
|
|
## Future Enhancements
|
|
|
|
### Short-term (1-3 months)
|
|
- Add range selector for time navigation
|
|
- Implement chart annotation for significant events
|
|
- Add export functionality for charts and data
|
|
|
|
### Medium-term (3-6 months)
|
|
- Multi-instrument support with tabs
|
|
- Advanced indicators and overlays
|
|
- User preference persistence
|
|
|
|
### Long-term (6+ months)
|
|
- Real-time alerts and notifications
|
|
- Strategy backtesting visualization
|
|
- Portfolio-level analytics
|
|
|
|
## Monitoring and Metrics
|
|
|
|
### Performance Monitoring
|
|
- Chart render times and update frequencies
|
|
- Memory usage growth over time
|
|
- Browser compatibility and error rates
|
|
- User interaction patterns
|
|
|
|
### Quality Metrics
|
|
- Chart accuracy compared to source data
|
|
- Visual responsiveness during heavy updates
|
|
- Error recovery from data corruption
|
|
|
|
## Review Triggers
|
|
Reconsider this decision if:
|
|
- Update frequency requirements exceed 10 Hz consistently
|
|
- Memory usage becomes prohibitive (> 1GB)
|
|
- Custom visualization requirements cannot be met
|
|
- Multi-user deployment becomes necessary
|
|
- Mobile responsiveness becomes a priority
|
|
- Integration with external charting libraries is needed
|
|
|
|
## Migration Path
|
|
If replacement becomes necessary:
|
|
1. **Phase 1**: Abstract chart building logic from Dash specifics
|
|
2. **Phase 2**: Implement alternative frontend while maintaining data formats
|
|
3. **Phase 3**: A/B test performance and usability
|
|
4. **Phase 4**: Complete migration with feature parity
|