- Introduced a new modular structure for the dashboard, enhancing maintainability and scalability. - Created main application entry point in `app_new.py`, integrating all components and callbacks. - Developed layout modules for market data, bot management, performance analytics, and system health in the `layouts` directory. - Implemented callback modules for navigation, charts, indicators, and system health in the `callbacks` directory. - Established reusable UI components in the `components` directory, including chart controls and indicator modals. - Enhanced documentation to reflect the new modular structure and provide clear usage guidelines. - Ensured all components are under 300-400 lines for better readability and maintainability.
121 lines
5.0 KiB
Python
121 lines
5.0 KiB
Python
"""
|
|
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") |