orderflow_backtest/docs/decisions/ADR-003-dash-visualization-framework.md

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:

  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