""" Chart-related callbacks for the dashboard. """ from dash import Output, Input from datetime import datetime from utils.logger import get_logger from components.charts import ( create_strategy_chart, create_chart_with_indicators, create_error_chart, get_market_statistics ) from components.charts.config import get_all_example_strategies from database.connection import DatabaseManager from dash import html logger = get_logger("chart_callbacks") def register_chart_callbacks(app): """Register chart-related callbacks.""" @app.callback( Output('price-chart', 'figure'), [Input('symbol-dropdown', 'value'), Input('timeframe-dropdown', 'value'), Input('overlay-indicators-checklist', 'value'), Input('subplot-indicators-checklist', 'value'), Input('strategy-dropdown', 'value'), Input('interval-component', 'n_intervals')] ) def update_price_chart(symbol, timeframe, overlay_indicators, subplot_indicators, selected_strategy, n_intervals): """Update the price chart with latest market data and selected indicators.""" try: # If a strategy is selected, use strategy chart if selected_strategy and selected_strategy != 'basic': fig = create_strategy_chart(symbol, timeframe, selected_strategy) logger.debug(f"Created strategy chart for {symbol} ({timeframe}) with strategy: {selected_strategy}") else: # Create chart with dynamically selected indicators fig = create_chart_with_indicators( symbol=symbol, timeframe=timeframe, overlay_indicators=overlay_indicators or [], subplot_indicators=subplot_indicators or [], days_back=7 ) indicator_count = len(overlay_indicators or []) + len(subplot_indicators or []) logger.debug(f"Created dynamic chart for {symbol} ({timeframe}) with {indicator_count} indicators") return fig except Exception as e: logger.error(f"Error updating price chart: {e}") return create_error_chart(f"Error loading chart: {str(e)}") # Strategy selection callback - automatically load strategy indicators @app.callback( [Output('overlay-indicators-checklist', 'value'), Output('subplot-indicators-checklist', 'value')], [Input('strategy-dropdown', 'value')] ) def update_indicators_from_strategy(selected_strategy): """Update indicator selections when a strategy is chosen.""" if not selected_strategy or selected_strategy == 'basic': return [], [] try: # Get strategy configuration all_strategies = get_all_example_strategies() if selected_strategy in all_strategies: strategy_example = all_strategies[selected_strategy] config = strategy_example.config # Extract overlay and subplot indicators from strategy overlay_indicators = config.overlay_indicators or [] # Extract subplot indicators from subplot configs subplot_indicators = [] for subplot_config in config.subplot_configs or []: subplot_indicators.extend(subplot_config.indicators or []) logger.debug(f"Loaded strategy {selected_strategy}: {len(overlay_indicators)} overlays, {len(subplot_indicators)} subplots") return overlay_indicators, subplot_indicators else: logger.warning(f"Strategy {selected_strategy} not found") return [], [] except Exception as e: logger.error(f"Error loading strategy indicators: {e}") return [], [] # Market statistics callback @app.callback( Output('market-stats', 'children'), [Input('symbol-dropdown', 'value'), Input('interval-component', 'n_intervals')] ) def update_market_stats(symbol, n_intervals): """Update market statistics.""" try: # Get real market statistics from database stats = get_market_statistics(symbol) return html.Div([ html.H3("Market Statistics"), html.Div([ html.Div([ html.Strong(f"{key}: "), html.Span(value, style={'color': '#27ae60' if '+' in str(value) else '#e74c3c' if '-' in str(value) else '#2c3e50'}) ], style={'margin': '5px 0'}) for key, value in stats.items() ]) ]) except Exception as e: logger.error(f"Error updating market stats: {e}") return html.Div("Error loading market statistics") logger.info("Chart callbacks registered successfully")