Remove deprecated app_new.py and consolidate main application logic into main.py
- Deleted `app_new.py`, which was previously the main entry point for the dashboard application, to streamline the codebase. - Consolidated the application initialization and callback registration logic into `main.py`, enhancing modularity and maintainability. - Updated the logging and error handling practices in `main.py` to ensure consistent application behavior and improved debugging capabilities. These changes simplify the application structure, aligning with project standards for modularity and maintainability.
This commit is contained in:
@@ -13,81 +13,68 @@ from dashboard.components.chart_controls import (
|
||||
create_time_range_controls,
|
||||
create_export_controls
|
||||
)
|
||||
from utils.timeframe_utils import load_timeframe_options
|
||||
|
||||
|
||||
logger = get_logger("default_logger")
|
||||
|
||||
|
||||
def get_market_data_layout():
|
||||
"""Create the market data visualization layout with indicator controls."""
|
||||
# Get available symbols and timeframes from database
|
||||
symbols = get_supported_symbols()
|
||||
timeframes = get_supported_timeframes()
|
||||
|
||||
# Create dropdown options
|
||||
def _create_dropdown_options(symbols, timeframes):
|
||||
"""Creates symbol and timeframe dropdown options."""
|
||||
symbol_options = [{'label': symbol, 'value': symbol} for symbol in symbols]
|
||||
timeframe_options = [
|
||||
{'label': "1 Second", 'value': '1s'},
|
||||
{'label': "5 Seconds", 'value': '5s'},
|
||||
{'label': "15 Seconds", 'value': '15s'},
|
||||
{'label': "30 Seconds", 'value': '30s'},
|
||||
{'label': '1 Minute', 'value': '1m'},
|
||||
{'label': '5 Minutes', 'value': '5m'},
|
||||
{'label': '15 Minutes', 'value': '15m'},
|
||||
{'label': '1 Hour', 'value': '1h'},
|
||||
{'label': '4 Hours', 'value': '4h'},
|
||||
{'label': '1 Day', 'value': '1d'},
|
||||
]
|
||||
all_timeframe_options = load_timeframe_options()
|
||||
|
||||
# Filter timeframe options to only show those available in database
|
||||
available_timeframes = [tf for tf in ['1s', '5s', '15s', '30s', '1m', '5m', '15m', '1h', '4h', '1d'] if tf in timeframes]
|
||||
if not available_timeframes:
|
||||
available_timeframes = ['5m'] # Default fallback
|
||||
available_timeframes_from_db = [tf for tf in [opt['value'] for opt in all_timeframe_options] if tf in timeframes]
|
||||
if not available_timeframes_from_db:
|
||||
available_timeframes_from_db = ['5m'] # Default fallback
|
||||
|
||||
timeframe_options = [opt for opt in timeframe_options if opt['value'] in available_timeframes]
|
||||
timeframe_options = [opt for opt in all_timeframe_options if opt['value'] in available_timeframes_from_db]
|
||||
|
||||
# Get available strategies and indicators
|
||||
return symbol_options, timeframe_options
|
||||
|
||||
def _load_strategy_and_indicator_options():
|
||||
"""Loads strategy and indicator options for chart configuration."""
|
||||
try:
|
||||
strategy_names = get_available_strategy_names()
|
||||
strategy_options = [{'label': name.replace('_', ' ').title(), 'value': name} for name in strategy_names]
|
||||
|
||||
# Get user indicators from the new indicator manager
|
||||
indicator_manager = get_indicator_manager()
|
||||
|
||||
# Ensure default indicators exist
|
||||
ensure_default_indicators()
|
||||
|
||||
# Get indicators by display type
|
||||
overlay_indicators = indicator_manager.get_indicators_by_type('overlay')
|
||||
subplot_indicators = indicator_manager.get_indicators_by_type('subplot')
|
||||
|
||||
# Create checkbox options for overlay indicators
|
||||
overlay_options = []
|
||||
for indicator in overlay_indicators:
|
||||
display_name = f"{indicator.name} ({indicator.type.upper()})"
|
||||
overlay_options.append({'label': display_name, 'value': indicator.id})
|
||||
|
||||
# Create checkbox options for subplot indicators
|
||||
subplot_options = []
|
||||
for indicator in subplot_indicators:
|
||||
display_name = f"{indicator.name} ({indicator.type.upper()})"
|
||||
subplot_options.append({'label': display_name, 'value': indicator.id})
|
||||
|
||||
return strategy_options, overlay_options, subplot_options
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"Market data layout: Error loading indicator options: {e}")
|
||||
strategy_options = [{'label': 'Basic Chart', 'value': 'basic'}]
|
||||
overlay_options = []
|
||||
subplot_options = []
|
||||
return [{'label': 'Basic Chart', 'value': 'basic'}], [], []
|
||||
|
||||
|
||||
def get_market_data_layout():
|
||||
"""Create the market data visualization layout with indicator controls."""
|
||||
symbols = get_supported_symbols()
|
||||
timeframes = get_supported_timeframes()
|
||||
|
||||
# Create components using the new modular functions
|
||||
symbol_options, timeframe_options = _create_dropdown_options(symbols, timeframes)
|
||||
strategy_options, overlay_options, subplot_options = _load_strategy_and_indicator_options()
|
||||
|
||||
chart_config_panel = create_chart_config_panel(strategy_options, overlay_options, subplot_options)
|
||||
time_range_controls = create_time_range_controls()
|
||||
export_controls = create_export_controls()
|
||||
|
||||
return html.Div([
|
||||
# Title and basic controls
|
||||
html.H3("💹 Market Data Visualization", style={'color': '#2c3e50', 'margin-bottom': '20px'}),
|
||||
|
||||
# Main chart controls
|
||||
html.Div([
|
||||
html.Div([
|
||||
html.Label("Symbol:", style={'font-weight': 'bold'}),
|
||||
@@ -111,21 +98,15 @@ def get_market_data_layout():
|
||||
], style={'width': '48%', 'float': 'right', 'display': 'inline-block'})
|
||||
], style={'margin-bottom': '20px'}),
|
||||
|
||||
# Chart Configuration Panel
|
||||
chart_config_panel,
|
||||
|
||||
# Time Range Controls (positioned under indicators, next to chart)
|
||||
time_range_controls,
|
||||
|
||||
# Export Controls
|
||||
export_controls,
|
||||
|
||||
# Chart
|
||||
dcc.Graph(id='price-chart'),
|
||||
|
||||
# Hidden store for chart data
|
||||
dcc.Store(id='chart-data-store'),
|
||||
|
||||
# Enhanced Market statistics with integrated data analysis
|
||||
html.Div(id='market-stats', style={'margin-top': '20px'})
|
||||
])
|
||||
@@ -5,127 +5,146 @@ System health monitoring layout for the dashboard.
|
||||
from dash import html
|
||||
import dash_bootstrap_components as dbc
|
||||
|
||||
def create_quick_status_card(title, component_id, icon):
|
||||
"""Helper to create a quick status card."""
|
||||
return dbc.Card(dbc.CardBody([
|
||||
html.H5(f"{icon} {title}", className="card-title"),
|
||||
html.Div(id=component_id, children=[
|
||||
dbc.Badge("Checking...", color="warning", className="me-1")
|
||||
])
|
||||
]), className="text-center")
|
||||
|
||||
def _create_header_section():
|
||||
"""Creates the header section for the system health layout."""
|
||||
return html.Div([
|
||||
html.H2("⚙️ System Health & Data Monitoring"),
|
||||
html.P("Real-time monitoring of data collection services, database health, and system performance",
|
||||
className="lead")
|
||||
], className="p-5 mb-4 bg-light rounded-3")
|
||||
|
||||
def _create_quick_status_row():
|
||||
"""Creates the quick status overview row."""
|
||||
return dbc.Row([
|
||||
dbc.Col(create_quick_status_card("Data Collection", "data-collection-quick-status", "📊"), width=3),
|
||||
dbc.Col(create_quick_status_card("Database", "database-quick-status", "🗄️"), width=3),
|
||||
dbc.Col(create_quick_status_card("Redis", "redis-quick-status", "🔗"), width=3),
|
||||
dbc.Col(create_quick_status_card("Performance", "performance-quick-status", "📈"), width=3),
|
||||
], className="mb-4")
|
||||
|
||||
def _create_data_collection_service_card():
|
||||
"""Creates the data collection service status card."""
|
||||
return dbc.Card([
|
||||
dbc.CardHeader(html.H4("📡 Data Collection Service")),
|
||||
dbc.CardBody([
|
||||
html.H5("Service Status", className="card-title"),
|
||||
html.Div(id='data-collection-service-status', className="mb-4"),
|
||||
|
||||
html.H5("Collection Metrics", className="card-title"),
|
||||
html.Div(id='data-collection-metrics', className="mb-4"),
|
||||
|
||||
html.H5("Service Controls", className="card-title"),
|
||||
dbc.ButtonGroup([
|
||||
dbc.Button("🔄 Refresh Status", id="refresh-data-status-btn", color="primary", outline=True, size="sm"),
|
||||
dbc.Button("📊 View Details", id="view-collection-details-btn", color="secondary", outline=True, size="sm"),
|
||||
dbc.Button("📋 View Logs", id="view-collection-logs-btn", color="info", outline=True, size="sm")
|
||||
])
|
||||
])
|
||||
], className="mb-4")
|
||||
|
||||
def _create_individual_collectors_card():
|
||||
"""Creates the individual collectors health card."""
|
||||
return dbc.Card([
|
||||
dbc.CardHeader(html.H4("🔌 Individual Collectors")),
|
||||
dbc.CardBody([
|
||||
html.Div(id='individual-collectors-status'),
|
||||
html.Div([
|
||||
dbc.Alert(
|
||||
"Collector health data will be displayed here when the data collection service is running.",
|
||||
id="collectors-info-alert",
|
||||
color="info",
|
||||
is_open=True,
|
||||
)
|
||||
], id='collectors-placeholder')
|
||||
])
|
||||
], className="mb-4")
|
||||
|
||||
def _create_database_status_card():
|
||||
"""Creates the database health status card."""
|
||||
return dbc.Card([
|
||||
dbc.CardHeader(html.H4("🗄️ Database Health")),
|
||||
dbc.CardBody([
|
||||
html.H5("Connection Status", className="card-title"),
|
||||
html.Div(id='database-status', className="mb-3"),
|
||||
html.Hr(),
|
||||
html.H5("Database Statistics", className="card-title"),
|
||||
html.Div(id='database-stats')
|
||||
])
|
||||
], className="mb-4")
|
||||
|
||||
def _create_redis_status_card():
|
||||
"""Creates the Redis health status card."""
|
||||
return dbc.Card([
|
||||
dbc.CardHeader(html.H4("🔗 Redis Status")),
|
||||
dbc.CardBody([
|
||||
html.H5("Connection Status", className="card-title"),
|
||||
html.Div(id='redis-status', className="mb-3"),
|
||||
html.Hr(),
|
||||
html.H5("Redis Statistics", className="card-title"),
|
||||
html.Div(id='redis-stats')
|
||||
])
|
||||
], className="mb-4")
|
||||
|
||||
def _create_system_performance_card():
|
||||
"""Creates the system performance metrics card."""
|
||||
return dbc.Card([
|
||||
dbc.CardHeader(html.H4("📈 System Performance")),
|
||||
dbc.CardBody([
|
||||
html.Div(id='system-performance-metrics')
|
||||
])
|
||||
], className="mb-4")
|
||||
|
||||
def _create_collection_details_modal():
|
||||
"""Creates the data collection details modal."""
|
||||
return dbc.Modal([
|
||||
dbc.ModalHeader(dbc.ModalTitle("📊 Data Collection Details")),
|
||||
dbc.ModalBody(id="collection-details-content")
|
||||
], id="collection-details-modal", is_open=False, size="lg")
|
||||
|
||||
def _create_collection_logs_modal():
|
||||
"""Creates the collection service logs modal."""
|
||||
return dbc.Modal([
|
||||
dbc.ModalHeader(dbc.ModalTitle("📋 Collection Service Logs")),
|
||||
dbc.ModalBody(
|
||||
html.Div(
|
||||
html.Pre(id="collection-logs-content", style={'max-height': '400px', 'overflow-y': 'auto'}),
|
||||
style={'white-space': 'pre-wrap', 'background-color': '#f8f9fa', 'padding': '15px', 'border-radius': '5px'}
|
||||
)
|
||||
),
|
||||
dbc.ModalFooter([
|
||||
dbc.Button("Refresh", id="refresh-logs-btn", color="primary"),
|
||||
dbc.Button("Close", id="close-logs-modal", color="secondary", className="ms-auto")
|
||||
])
|
||||
], id="collection-logs-modal", is_open=False, size="xl")
|
||||
|
||||
def get_system_health_layout():
|
||||
"""Create the enhanced system health monitoring layout with Bootstrap components."""
|
||||
|
||||
def create_quick_status_card(title, component_id, icon):
|
||||
return dbc.Card(dbc.CardBody([
|
||||
html.H5(f"{icon} {title}", className="card-title"),
|
||||
html.Div(id=component_id, children=[
|
||||
dbc.Badge("Checking...", color="warning", className="me-1")
|
||||
])
|
||||
]), className="text-center")
|
||||
|
||||
return html.Div([
|
||||
# Header section
|
||||
html.Div([
|
||||
html.H2("⚙️ System Health & Data Monitoring"),
|
||||
html.P("Real-time monitoring of data collection services, database health, and system performance",
|
||||
className="lead")
|
||||
], className="p-5 mb-4 bg-light rounded-3"),
|
||||
_create_header_section(),
|
||||
_create_quick_status_row(),
|
||||
|
||||
# Quick Status Overview Row
|
||||
dbc.Row([
|
||||
dbc.Col(create_quick_status_card("Data Collection", "data-collection-quick-status", "📊"), width=3),
|
||||
dbc.Col(create_quick_status_card("Database", "database-quick-status", "🗄️"), width=3),
|
||||
dbc.Col(create_quick_status_card("Redis", "redis-quick-status", "🔗"), width=3),
|
||||
dbc.Col(create_quick_status_card("Performance", "performance-quick-status", "📈"), width=3),
|
||||
], className="mb-4"),
|
||||
|
||||
# Detailed Monitoring Sections
|
||||
dbc.Row([
|
||||
# Left Column - Data Collection Service
|
||||
dbc.Col([
|
||||
# Data Collection Service Status
|
||||
dbc.Card([
|
||||
dbc.CardHeader(html.H4("📡 Data Collection Service")),
|
||||
dbc.CardBody([
|
||||
html.H5("Service Status", className="card-title"),
|
||||
html.Div(id='data-collection-service-status', className="mb-4"),
|
||||
|
||||
html.H5("Collection Metrics", className="card-title"),
|
||||
html.Div(id='data-collection-metrics', className="mb-4"),
|
||||
|
||||
html.H5("Service Controls", className="card-title"),
|
||||
dbc.ButtonGroup([
|
||||
dbc.Button("🔄 Refresh Status", id="refresh-data-status-btn", color="primary", outline=True, size="sm"),
|
||||
dbc.Button("📊 View Details", id="view-collection-details-btn", color="secondary", outline=True, size="sm"),
|
||||
dbc.Button("📋 View Logs", id="view-collection-logs-btn", color="info", outline=True, size="sm")
|
||||
])
|
||||
])
|
||||
], className="mb-4"),
|
||||
|
||||
# Data Collector Health
|
||||
dbc.Card([
|
||||
dbc.CardHeader(html.H4("🔌 Individual Collectors")),
|
||||
dbc.CardBody([
|
||||
html.Div(id='individual-collectors-status'),
|
||||
html.Div([
|
||||
dbc.Alert(
|
||||
"Collector health data will be displayed here when the data collection service is running.",
|
||||
id="collectors-info-alert",
|
||||
color="info",
|
||||
is_open=True,
|
||||
)
|
||||
], id='collectors-placeholder')
|
||||
])
|
||||
], className="mb-4"),
|
||||
_create_data_collection_service_card(),
|
||||
_create_individual_collectors_card(),
|
||||
], width=6),
|
||||
|
||||
# Right Column - System Health
|
||||
dbc.Col([
|
||||
# Database Status
|
||||
dbc.Card([
|
||||
dbc.CardHeader(html.H4("🗄️ Database Health")),
|
||||
dbc.CardBody([
|
||||
html.H5("Connection Status", className="card-title"),
|
||||
html.Div(id='database-status', className="mb-3"),
|
||||
html.Hr(),
|
||||
html.H5("Database Statistics", className="card-title"),
|
||||
html.Div(id='database-stats')
|
||||
])
|
||||
], className="mb-4"),
|
||||
|
||||
# Redis Status
|
||||
dbc.Card([
|
||||
dbc.CardHeader(html.H4("🔗 Redis Status")),
|
||||
dbc.CardBody([
|
||||
html.H5("Connection Status", className="card-title"),
|
||||
html.Div(id='redis-status', className="mb-3"),
|
||||
html.Hr(),
|
||||
html.H5("Redis Statistics", className="card-title"),
|
||||
html.Div(id='redis-stats')
|
||||
])
|
||||
], className="mb-4"),
|
||||
|
||||
# System Performance
|
||||
dbc.Card([
|
||||
dbc.CardHeader(html.H4("📈 System Performance")),
|
||||
dbc.CardBody([
|
||||
html.Div(id='system-performance-metrics')
|
||||
])
|
||||
], className="mb-4"),
|
||||
_create_database_status_card(),
|
||||
_create_redis_status_card(),
|
||||
_create_system_performance_card(),
|
||||
], width=6)
|
||||
]),
|
||||
|
||||
# Data Collection Details Modal
|
||||
dbc.Modal([
|
||||
dbc.ModalHeader(dbc.ModalTitle("📊 Data Collection Details")),
|
||||
dbc.ModalBody(id="collection-details-content")
|
||||
], id="collection-details-modal", is_open=False, size="lg"),
|
||||
|
||||
# Collection Logs Modal
|
||||
dbc.Modal([
|
||||
dbc.ModalHeader(dbc.ModalTitle("📋 Collection Service Logs")),
|
||||
dbc.ModalBody(
|
||||
html.Div(
|
||||
html.Pre(id="collection-logs-content", style={'max-height': '400px', 'overflow-y': 'auto'}),
|
||||
style={'white-space': 'pre-wrap', 'background-color': '#f8f9fa', 'padding': '15px', 'border-radius': '5px'}
|
||||
)
|
||||
),
|
||||
dbc.ModalFooter([
|
||||
dbc.Button("Refresh", id="refresh-logs-btn", color="primary"),
|
||||
dbc.Button("Close", id="close-logs-modal", color="secondary", className="ms-auto")
|
||||
])
|
||||
], id="collection-logs-modal", is_open=False, size="xl")
|
||||
_create_collection_details_modal(),
|
||||
_create_collection_logs_modal()
|
||||
])
|
||||
Reference in New Issue
Block a user