diff --git a/ANNOTATE/web/app.py b/ANNOTATE/web/app.py index 2d22553..f602f00 100644 --- a/ANNOTATE/web/app.py +++ b/ANNOTATE/web/app.py @@ -632,31 +632,63 @@ class AnnotationDashboard: self.training_adapter.orchestrator = self.orchestrator logger.info("TradingOrchestrator initialized") + # Get checkpoint info before loading + checkpoint_info = self._get_best_checkpoint_info(model_name) + # Load the specific model if model_name == 'Transformer': logger.info("Loading Transformer model...") self.orchestrator.load_transformer_model() self.loaded_models['Transformer'] = self.orchestrator.primary_transformer_trainer + + # Store checkpoint info in orchestrator for UI access + if checkpoint_info: + self.orchestrator.transformer_checkpoint_info = { + 'status': 'loaded', + 'filename': checkpoint_info.get('filename', 'unknown'), + 'epoch': checkpoint_info.get('epoch', 0), + 'loss': checkpoint_info.get('loss', 0.0), + 'accuracy': checkpoint_info.get('accuracy', 0.0), + 'loaded_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S') + } + logger.info("Transformer model loaded successfully") elif model_name == 'CNN': logger.info("Loading CNN model...") self.orchestrator.load_cnn_model() self.loaded_models['CNN'] = self.orchestrator.cnn_model + + # Store checkpoint info + if checkpoint_info: + self.orchestrator.cnn_checkpoint_info = { + 'status': 'loaded', + 'filename': checkpoint_info.get('filename', 'unknown'), + 'loaded_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S') + } + logger.info("CNN model loaded successfully") elif model_name == 'DQN': logger.info("Loading DQN model...") self.orchestrator.load_dqn_model() self.loaded_models['DQN'] = self.orchestrator.dqn_agent + + # Store checkpoint info + if checkpoint_info: + self.orchestrator.dqn_checkpoint_info = { + 'status': 'loaded', + 'filename': checkpoint_info.get('filename', 'unknown'), + 'loaded_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S') + } + logger.info("DQN model loaded successfully") else: logger.warning(f"Unknown model name: {model_name}") return - # Get checkpoint info for display - checkpoint_info = self._get_best_checkpoint_info(model_name) + # Log checkpoint info if checkpoint_info: logger.info(f" Checkpoint: {checkpoint_info.get('filename', 'N/A')}") if checkpoint_info.get('accuracy'): @@ -2013,23 +2045,27 @@ class AnnotationDashboard: logger.warning(f"self.available_models is not a list: {type(self.available_models)}. Resetting to default.") self.available_models = ['Transformer', 'COB_RL', 'CNN', 'DQN'] - # Ensure self.loaded_models is a list/set + # Ensure self.loaded_models exists (it's a dict) if not hasattr(self, 'loaded_models'): - self.loaded_models = [] + self.loaded_models = {} # Build model state dict with checkpoint info logger.info(f"Building model states for {len(self.available_models)} models: {self.available_models}") + logger.info(f"Currently loaded models: {list(self.loaded_models.keys())}") model_states = [] for model_name in self.available_models: - is_loaded = model_name in self.loaded_models + # Check if model is in loaded_models dict + is_loaded = model_name in self.loaded_models and self.loaded_models[model_name] is not None # Get checkpoint info (even for unloaded models) checkpoint_info = None # If loaded, get from orchestrator if is_loaded and self.orchestrator: - if model_name == 'Transformer' and hasattr(self.orchestrator, 'transformer_checkpoint_info'): - cp_info = self.orchestrator.transformer_checkpoint_info + checkpoint_attr = f"{model_name.lower()}_checkpoint_info" + + if hasattr(self.orchestrator, checkpoint_attr): + cp_info = getattr(self.orchestrator, checkpoint_attr) if cp_info and cp_info.get('status') == 'loaded': checkpoint_info = { 'filename': cp_info.get('filename', 'unknown'), diff --git a/ANNOTATE/web/static/js/chart_manager.js b/ANNOTATE/web/static/js/chart_manager.js index 0c7c833..74dec7c 100644 --- a/ANNOTATE/web/static/js/chart_manager.js +++ b/ANNOTATE/web/static/js/chart_manager.js @@ -441,7 +441,8 @@ class ChartManager { showgrid: true, zeroline: false, domain: [0.3, 1], - fixedrange: false // Allow vertical scaling + fixedrange: false, // Allow vertical scaling by dragging Y-axis + autorange: true }, yaxis2: { title: { @@ -453,7 +454,8 @@ class ChartManager { showgrid: false, zeroline: false, domain: [0, 0.25], - fixedrange: false + fixedrange: false, // Allow vertical scaling + autorange: true }, plot_bgcolor: '#1f2937', paper_bgcolor: '#1f2937', @@ -472,10 +474,23 @@ class ChartManager { modeBarButtonsToRemove: ['lasso2d', 'select2d'], // Allow autoScale2d displaylogo: false, scrollZoom: true, - // Performance optimizations - doubleClick: 'reset', // Enable double-click reset - showAxisDragHandles: true, // Enable axis dragging - showAxisRangeEntryBoxes: false + // Enable vertical scaling by dragging Y-axis + doubleClick: 'reset', // Double-click to reset zoom + showAxisDragHandles: true, // Show drag handles on axes + showAxisRangeEntryBoxes: true, // Allow manual range entry + // Axis drag behavior + editable: true, // Make axes editable + edits: { + axisTitleText: false, + colorbarPosition: false, + colorbarTitleText: false, + legendPosition: false, + legendText: false, + shapePosition: true, + annotationPosition: true, + annotationTail: true, + annotationText: false + } }; // Prepare chart data with pivot bounds @@ -2368,13 +2383,20 @@ class ChartManager { if (!plotElement) return; - // Create or update metrics overlay - let overlay = document.getElementById(`metrics-overlay-${activeTimeframe}`); + // Remove any existing overlays from other timeframes + document.querySelectorAll('[id^="metrics-overlay-"]').forEach(el => { + if (el.id !== 'metrics-overlay') { + el.remove(); + } + }); + + // Create or update single metrics overlay + let overlay = document.getElementById('metrics-overlay'); if (!overlay) { // Create overlay div overlay = document.createElement('div'); - overlay.id = `metrics-overlay-${activeTimeframe}`; + overlay.id = 'metrics-overlay'; overlay.style.cssText = ` position: absolute; top: 10px; @@ -2437,12 +2459,19 @@ class ChartManager { * Remove live metrics overlay */ removeLiveMetrics() { - if (this.liveMetricsOverlay) { - this.liveMetricsOverlay.remove(); - this.liveMetricsOverlay = null; + // Remove the single metrics overlay + const overlay = document.getElementById('metrics-overlay'); + if (overlay) { + overlay.remove(); } - // Remove all overlays - document.querySelectorAll('[id^="metrics-overlay-"]').forEach(el => el.remove()); + // Also remove any old overlays with timeframe-specific IDs (cleanup) + document.querySelectorAll('[id^="metrics-overlay-"]').forEach(el => { + if (el.id !== 'metrics-overlay') { + el.remove(); + } + }); + + this.liveMetricsOverlay = null; } }