fix trend line training

This commit is contained in:
Dobromir Popov
2025-12-10 14:20:51 +02:00
parent 83bb688158
commit e200600a0a
4 changed files with 600 additions and 3845 deletions

View File

@@ -521,6 +521,9 @@ class TradingOrchestrator:
self.training_sessions = {} # Track active training sessions
logger.info("Integrated training coordination initialized in orchestrator")
# Initialize trend line training system
self.__init_trend_line_training()
# CRITICAL: Initialize model_states dictionary to track model performance
self.model_states: Dict[str, Dict[str, Any]] = {
"dqn": {
@@ -3123,4 +3126,351 @@ class TradingOrchestrator:
logger.warning(f"Inference frame not found: {inference_id}")
except Exception as e:
logger.error(f"Error updating inference frame results: {e}")
logger.error(f"Error updating inference frame results: {e}")
# ===== TREND LINE TRAINING SYSTEM =====
# Implements automatic trend line detection and model training
def __init_trend_line_training(self):
"""Initialize trend line training system"""
try:
self.trend_line_predictions = {} # Store trend predictions waiting for validation
self.l2_pivot_history = {} # Track L2 pivots per symbol/timeframe
self.trend_line_training_enabled = True
# Subscribe to pivot events from data provider
if hasattr(self.data_provider, 'subscribe_pivot_events'):
self.data_provider.subscribe_pivot_events(
callback=self._on_pivot_detected,
symbol='ETH/USDT', # Main trading symbol
timeframe='1m', # Main timeframe for trend detection
pivot_types=['L2L', 'L2H'] # Level 2 lows and highs
)
logger.info("Subscribed to L2 pivot events for trend line training")
except Exception as e:
logger.error(f"Error initializing trend line training: {e}")
def store_trend_prediction(self, symbol: str, timeframe: str, prediction_data: Dict):
"""
Store a trend prediction that will be validated when L2 pivots form
Args:
symbol: Trading symbol
timeframe: Timeframe
prediction_data: {
'prediction_id': str,
'timestamp': datetime,
'predicted_trend': 'up'|'down'|'sideways',
'confidence': float,
'model_type': str,
'target_price': float (optional),
'prediction_horizon': int (minutes)
}
"""
try:
key = f"{symbol}_{timeframe}"
if key not in self.trend_line_predictions:
self.trend_line_predictions[key] = []
# Add prediction to waiting list
self.trend_line_predictions[key].append({
**prediction_data,
'status': 'waiting_for_validation',
'l2_pivots_after': [], # Will collect L2 pivots that form after this prediction
'created_at': datetime.now()
})
# Keep only last 10 predictions per symbol/timeframe
self.trend_line_predictions[key] = self.trend_line_predictions[key][-10:]
logger.info(f"Stored trend prediction for validation: {prediction_data['prediction_id']} - {prediction_data['predicted_trend']}")
except Exception as e:
logger.error(f"Error storing trend prediction: {e}")
def _on_pivot_detected(self, event_data: Dict):
"""
Handle L2 pivot detection events
Args:
event_data: {
'symbol': str,
'timeframe': str,
'pivot_type': 'L2L'|'L2H',
'timestamp': datetime,
'price': float,
'strength': float
}
"""
try:
symbol = event_data['symbol']
timeframe = event_data['timeframe']
pivot_type = event_data['pivot_type']
timestamp = event_data['timestamp']
price = event_data['price']
key = f"{symbol}_{timeframe}"
# Track L2 pivot history
if key not in self.l2_pivot_history:
self.l2_pivot_history[key] = []
pivot_info = {
'type': pivot_type,
'timestamp': timestamp,
'price': price,
'strength': event_data.get('strength', 1.0)
}
self.l2_pivot_history[key].append(pivot_info)
# Keep only last 20 L2 pivots
self.l2_pivot_history[key] = self.l2_pivot_history[key][-20:]
logger.info(f"L2 pivot detected: {symbol} {timeframe} {pivot_type} @ {price} at {timestamp}")
# Check if this pivot validates any trend predictions
self._check_trend_validation(symbol, timeframe, pivot_info)
except Exception as e:
logger.error(f"Error handling pivot detection: {e}")
def _check_trend_validation(self, symbol: str, timeframe: str, new_pivot: Dict):
"""
Check if the new L2 pivot validates any trend predictions
Args:
symbol: Trading symbol
timeframe: Timeframe
new_pivot: Latest L2 pivot info
"""
try:
key = f"{symbol}_{timeframe}"
if key not in self.trend_line_predictions:
return
# Check each waiting prediction
for prediction in self.trend_line_predictions[key]:
if prediction['status'] != 'waiting_for_validation':
continue
# Only consider pivots that formed AFTER the prediction
if new_pivot['timestamp'] <= prediction['timestamp']:
continue
# Add this pivot to the prediction's validation list
prediction['l2_pivots_after'].append(new_pivot)
# Check if we have 2 L2 pivots of the same type after the prediction
pivot_types = [p['type'] for p in prediction['l2_pivots_after']]
# Count consecutive pivots of same type
l2h_count = pivot_types.count('L2H')
l2l_count = pivot_types.count('L2L')
if l2h_count >= 2 or l2l_count >= 2:
# We have 2+ L2 pivots of same type - create trend line and train
self._create_trend_line_and_train(symbol, timeframe, prediction)
except Exception as e:
logger.error(f"Error checking trend validation: {e}")
def _create_trend_line_and_train(self, symbol: str, timeframe: str, prediction: Dict):
"""
Create trend line from L2 pivots and trigger model training
Args:
symbol: Trading symbol
timeframe: Timeframe
prediction: Prediction data with L2 pivots
"""
try:
# Get the L2 pivots that formed after prediction
pivots = prediction['l2_pivots_after']
# Find 2 pivots of the same type for trend line
l2h_pivots = [p for p in pivots if p['type'] == 'L2H']
l2l_pivots = [p for p in pivots if p['type'] == 'L2L']
trend_line = None
actual_trend = None
if len(l2h_pivots) >= 2:
# Create trend line from 2 L2 highs
p1, p2 = l2h_pivots[0], l2h_pivots[1]
trend_line = self._calculate_trend_line(p1, p2)
actual_trend = 'down' if p2['price'] < p1['price'] else 'up'
logger.info(f"Created trend line from 2 L2H pivots: {actual_trend} trend")
elif len(l2l_pivots) >= 2:
# Create trend line from 2 L2 lows
p1, p2 = l2l_pivots[0], l2l_pivots[1]
trend_line = self._calculate_trend_line(p1, p2)
actual_trend = 'up' if p2['price'] > p1['price'] else 'down'
logger.info(f"Created trend line from 2 L2L pivots: {actual_trend} trend")
if trend_line and actual_trend:
# Compare predicted vs actual trend
predicted_trend = prediction['predicted_trend']
is_correct = (predicted_trend == actual_trend)
logger.info(f"Trend validation: Predicted={predicted_trend}, Actual={actual_trend}, Correct={is_correct}")
# Create training data for backpropagation
training_data = {
'prediction_id': prediction['prediction_id'],
'symbol': symbol,
'timeframe': timeframe,
'prediction_timestamp': prediction['timestamp'],
'validation_timestamp': datetime.now(),
'predicted_trend': predicted_trend,
'actual_trend': actual_trend,
'is_correct': is_correct,
'confidence': prediction['confidence'],
'model_type': prediction['model_type'],
'trend_line': trend_line,
'l2_pivots': pivots
}
# Trigger model training with trend validation data
self._trigger_trend_training(training_data)
# Mark prediction as validated
prediction['status'] = 'validated'
prediction['validation_result'] = training_data
except Exception as e:
logger.error(f"Error creating trend line and training: {e}")
def _calculate_trend_line(self, pivot1: Dict, pivot2: Dict) -> Dict:
"""Calculate trend line parameters from 2 pivots"""
try:
# Calculate slope and intercept
x1 = pivot1['timestamp'].timestamp()
y1 = pivot1['price']
x2 = pivot2['timestamp'].timestamp()
y2 = pivot2['price']
slope = (y2 - y1) / (x2 - x1) if x2 != x1 else 0
intercept = y1 - slope * x1
return {
'slope': slope,
'intercept': intercept,
'start_time': pivot1['timestamp'],
'end_time': pivot2['timestamp'],
'start_price': y1,
'end_price': y2,
'price_change': y2 - y1,
'time_duration': x2 - x1
}
except Exception as e:
logger.error(f"Error calculating trend line: {e}")
return {}
def _trigger_trend_training(self, training_data: Dict):
"""
Trigger model training with trend validation data
Args:
training_data: Trend validation results for training
"""
try:
model_type = training_data['model_type']
is_correct = training_data['is_correct']
logger.info(f"Triggering trend training for {model_type}: {'Correct' if is_correct else 'Incorrect'} prediction")
# Create training event
training_event = {
'event_type': 'trend_validation',
'symbol': training_data['symbol'],
'timeframe': training_data['timeframe'],
'model_type': model_type,
'training_data': training_data,
'training_type': 'backpropagation',
'priority': 'high' if not is_correct else 'normal' # Prioritize incorrect predictions
}
# Trigger training through the integrated training system
self.trigger_training_on_event('trend_validation', training_event)
# Store training session
session_id = self.start_training_session(
symbol=training_data['symbol'],
timeframe=training_data['timeframe'],
model_type=f"{model_type}_trend_validation"
)
logger.info(f"Started trend validation training session: {session_id}")
except Exception as e:
logger.error(f"Error triggering trend training: {e}")
def get_trend_training_stats(self) -> Dict[str, Any]:
"""Get trend line training statistics"""
try:
stats = {
'total_predictions': 0,
'validated_predictions': 0,
'correct_predictions': 0,
'accuracy': 0.0,
'pending_validations': 0,
'recent_trend_lines': []
}
for key, predictions in self.trend_line_predictions.items():
stats['total_predictions'] += len(predictions)
for pred in predictions:
if pred['status'] == 'validated':
stats['validated_predictions'] += 1
if pred.get('validation_result', {}).get('is_correct'):
stats['correct_predictions'] += 1
elif pred['status'] == 'waiting_for_validation':
stats['pending_validations'] += 1
if stats['validated_predictions'] > 0:
stats['accuracy'] = stats['correct_predictions'] / stats['validated_predictions']
return stats
except Exception as e:
logger.error(f"Error getting trend training stats: {e}")
return {}
def store_model_trend_prediction(self, model_type: str, symbol: str, timeframe: str,
predicted_trend: str, confidence: float,
target_price: float = None, horizon_minutes: int = 60):
"""
Store a trend prediction from a model for later validation
Args:
model_type: 'transformer', 'cnn', 'dqn', etc.
symbol: Trading symbol
timeframe: Timeframe
predicted_trend: 'up', 'down', or 'sideways'
confidence: Prediction confidence (0.0 to 1.0)
target_price: Optional target price
horizon_minutes: Prediction horizon in minutes
"""
try:
prediction_data = {
'prediction_id': f"{model_type}_{symbol}_{int(datetime.now().timestamp())}",
'timestamp': datetime.now(),
'predicted_trend': predicted_trend,
'confidence': confidence,
'model_type': model_type,
'target_price': target_price,
'prediction_horizon': horizon_minutes
}
self.store_trend_prediction(symbol, timeframe, prediction_data)
logger.info(f"Stored {model_type} trend prediction: {predicted_trend} (confidence: {confidence:.2f})")
except Exception as e:
logger.error(f"Error storing model trend prediction: {e}")