6.9 KiB
6.9 KiB
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
# 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
# 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
@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
# 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:
- Phase 1: Abstract chart building logic from Dash specifics
- Phase 2: Implement alternative frontend while maintaining data formats
- Phase 3: A/B test performance and usability
- Phase 4: Complete migration with feature parity