merge annotate /ANNOTATE/core into /core.

fix chart updates
This commit is contained in:
Dobromir Popov
2025-12-10 14:07:14 +02:00
parent e0d0471e8a
commit bfaba556ea
23 changed files with 1074 additions and 1214 deletions

View File

@@ -70,6 +70,7 @@ from NN.models.model_interfaces import (
from .config import get_config
from .data_provider import DataProvider
from .data_models import InferenceFrameReference, TrainingSession
from .universal_data_adapter import UniversalDataAdapter, UniversalDataStream
# Import COB integration for real-time market microstructure data
@@ -513,20 +514,12 @@ class TradingOrchestrator:
self.inference_logger = None # Will be initialized later if needed
self.db_manager = None # Will be initialized later if needed
# Inference Training Coordinator - manages inference frame references and training events
# Integrated into orchestrator to reduce duplication and centralize coordination
self.inference_training_coordinator = None
try:
from ANNOTATE.core.inference_training_system import InferenceTrainingCoordinator
duckdb_storage = getattr(self.data_provider, 'duckdb_storage', None)
self.inference_training_coordinator = InferenceTrainingCoordinator(
data_provider=self.data_provider,
duckdb_storage=duckdb_storage
)
logger.info("InferenceTrainingCoordinator initialized in orchestrator")
except Exception as e:
logger.warning(f"Could not initialize InferenceTrainingCoordinator: {e}")
self.inference_training_coordinator = None
# Integrated Training Coordination (moved from ANNOTATE/core for unified architecture)
# Manages inference frame references and training events directly in orchestrator
self.training_event_subscribers = []
self.inference_frames = {} # Store inference frames by ID
self.training_sessions = {} # Track active training sessions
logger.info("Integrated training coordination initialized in orchestrator")
# CRITICAL: Initialize model_states dictionary to track model performance
self.model_states: Dict[str, Dict[str, Any]] = {
@@ -2965,3 +2958,169 @@ class TradingOrchestrator:
except Exception as e:
logger.error(f"Error clearing predictions: {e}")
# ===== INTEGRATED TRAINING COORDINATION METHODS =====
# Moved from ANNOTATE/core/inference_training_system.py for unified architecture
def subscribe_training_events(self, callback, event_types: List[str]):
"""Subscribe to training events (candle completion, pivot events, etc.)"""
try:
subscriber = {
'callback': callback,
'event_types': event_types,
'id': f"subscriber_{len(self.training_event_subscribers)}"
}
self.training_event_subscribers.append(subscriber)
logger.info(f"Registered training event subscriber for events: {event_types}")
except Exception as e:
logger.error(f"Error subscribing to training events: {e}")
def store_inference_frame(self, symbol: str, timeframe: str, prediction_data: Dict) -> str:
"""Store inference frame reference for later training"""
try:
from uuid import uuid4
inference_id = str(uuid4())
# Create inference frame reference
frame_ref = InferenceFrameReference(
inference_id=inference_id,
symbol=symbol,
timeframe=timeframe,
prediction_timestamp=datetime.now(),
predicted_action=prediction_data.get('action'),
predicted_price=prediction_data.get('predicted_price'),
confidence=prediction_data.get('confidence', 0.0),
model_type=prediction_data.get('model_type', 'transformer'),
data_range_start=prediction_data.get('data_range_start', datetime.now() - timedelta(hours=1)),
data_range_end=prediction_data.get('data_range_end', datetime.now())
)
# Store in memory
self.inference_frames[inference_id] = frame_ref
# Store in DuckDB if available
if hasattr(self.data_provider, 'duckdb_storage') and self.data_provider.duckdb_storage:
try:
# Store inference frame in DuckDB for persistence
# This would be implemented based on the DuckDB schema
pass
except Exception as e:
logger.debug(f"Could not store inference frame in DuckDB: {e}")
logger.debug(f"Stored inference frame: {inference_id} for {symbol} {timeframe}")
return inference_id
except Exception as e:
logger.error(f"Error storing inference frame: {e}")
return ""
def trigger_training_on_event(self, event_type: str, event_data: Dict):
"""Trigger training based on events (candle completion, pivot detection, etc.)"""
try:
# Notify all subscribers interested in this event type
for subscriber in self.training_event_subscribers:
if event_type in subscriber['event_types']:
try:
subscriber['callback'](event_type, event_data)
except Exception as e:
logger.error(f"Error in training event callback: {e}")
logger.debug(f"Triggered training event: {event_type}")
except Exception as e:
logger.error(f"Error triggering training event: {e}")
def start_training_session(self, symbol: str, timeframe: str, model_type: str) -> str:
"""Start a new training session"""
try:
from uuid import uuid4
session_id = str(uuid4())
session = TrainingSession(
training_id=session_id,
symbol=symbol,
timeframe=timeframe,
model_type=model_type,
start_time=datetime.now(),
status='running'
)
self.training_sessions[session_id] = session
logger.info(f"Started training session: {session_id} for {symbol} {timeframe} {model_type}")
return session_id
except Exception as e:
logger.error(f"Error starting training session: {e}")
return ""
def complete_training_session(self, session_id: str, loss: float = None, accuracy: float = None, samples_trained: int = 0):
"""Complete a training session with results"""
try:
if session_id in self.training_sessions:
session = self.training_sessions[session_id]
session.end_time = datetime.now()
session.status = 'completed'
session.loss = loss
session.accuracy = accuracy
session.samples_trained = samples_trained
logger.info(f"Completed training session: {session_id} - Loss: {loss}, Accuracy: {accuracy}, Samples: {samples_trained}")
else:
logger.warning(f"Training session not found: {session_id}")
except Exception as e:
logger.error(f"Error completing training session: {e}")
def get_training_session_status(self, session_id: str) -> Optional[Dict]:
"""Get status of a training session"""
try:
if session_id in self.training_sessions:
session = self.training_sessions[session_id]
return {
'training_id': session.training_id,
'symbol': session.symbol,
'timeframe': session.timeframe,
'model_type': session.model_type,
'status': session.status,
'start_time': session.start_time.isoformat() if session.start_time else None,
'end_time': session.end_time.isoformat() if session.end_time else None,
'loss': session.loss,
'accuracy': session.accuracy,
'samples_trained': session.samples_trained
}
return None
except Exception as e:
logger.error(f"Error getting training session status: {e}")
return None
def get_inference_frame(self, inference_id: str) -> Optional[InferenceFrameReference]:
"""Get stored inference frame by ID"""
return self.inference_frames.get(inference_id)
def update_inference_frame_results(self, inference_id: str, actual_candle: List[float], actual_price: float):
"""Update inference frame with actual results for training"""
try:
if inference_id in self.inference_frames:
frame_ref = self.inference_frames[inference_id]
frame_ref.actual_candle = actual_candle
frame_ref.actual_price = actual_price
# Calculate prediction error
if frame_ref.predicted_price and actual_price:
frame_ref.prediction_error = abs(frame_ref.predicted_price - actual_price)
# Check direction correctness
if frame_ref.predicted_action and len(actual_candle) >= 4:
open_price, close_price = actual_candle[0], actual_candle[3]
actual_direction = 'BUY' if close_price > open_price else 'SELL' if close_price < open_price else 'HOLD'
frame_ref.direction_correct = (frame_ref.predicted_action == actual_direction)
logger.debug(f"Updated inference frame results: {inference_id}")
else:
logger.warning(f"Inference frame not found: {inference_id}")
except Exception as e:
logger.error(f"Error updating inference frame results: {e}")