wip
This commit is contained in:
@@ -345,18 +345,61 @@ class CleanTradingDashboard:
|
||||
'timestamp': datetime.now().isoformat()
|
||||
})
|
||||
|
||||
@self.app.server.route('/api/predictions/stats', methods=['GET'])
|
||||
def get_prediction_stats():
|
||||
"""Get model prediction statistics"""
|
||||
@self.app.server.route('/api/predictions/recent', methods=['GET'])
|
||||
def get_recent_predictions():
|
||||
"""Get recent predictions with their outcomes"""
|
||||
try:
|
||||
if (hasattr(self.orchestrator, 'enhanced_training_system') and
|
||||
self.orchestrator.enhanced_training_system):
|
||||
stats = self.orchestrator.enhanced_training_system.get_model_performance_stats()
|
||||
return jsonify(stats)
|
||||
|
||||
# Get predictions from database
|
||||
from core.prediction_database import get_prediction_db
|
||||
db = get_prediction_db()
|
||||
|
||||
# Get recent predictions (last 24 hours)
|
||||
predictions = []
|
||||
|
||||
# Mock data for now - replace with actual database query
|
||||
import sqlite3
|
||||
try:
|
||||
with sqlite3.connect(db.db_path) as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("""
|
||||
SELECT model_name, symbol, prediction_type, confidence,
|
||||
timestamp, price_at_prediction, outcome_timestamp,
|
||||
actual_price_change, reward, is_correct
|
||||
FROM predictions
|
||||
ORDER BY timestamp DESC
|
||||
LIMIT 50
|
||||
""")
|
||||
|
||||
for row in cursor.fetchall():
|
||||
predictions.append({
|
||||
'model_name': row[0],
|
||||
'symbol': row[1],
|
||||
'prediction_type': row[2],
|
||||
'confidence': row[3],
|
||||
'timestamp': row[4],
|
||||
'price_at_prediction': row[5],
|
||||
'outcome_timestamp': row[6],
|
||||
'actual_price_change': row[7],
|
||||
'reward': row[8],
|
||||
'is_correct': row[9],
|
||||
'is_resolved': row[6] is not None
|
||||
})
|
||||
except Exception as e:
|
||||
logger.debug(f"Error fetching predictions from database: {e}")
|
||||
|
||||
return jsonify({
|
||||
'predictions': predictions,
|
||||
'total_predictions': len(predictions),
|
||||
'active_predictions': len([p for p in predictions if not p['is_resolved']]),
|
||||
'timestamp': datetime.now().isoformat()
|
||||
})
|
||||
else:
|
||||
return jsonify({"error": "Training system not available"}), 503
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting prediction stats: {e}")
|
||||
logger.error(f"Error getting recent predictions: {e}")
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
def _get_ohlcv_data_with_indicators(self, symbol: str, timeframe: str, limit: int = 300):
|
||||
@@ -980,6 +1023,135 @@ class CleanTradingDashboard:
|
||||
logger.error(f"Training status error: {e}")
|
||||
return 'Error', 'badge bg-danger small'
|
||||
|
||||
@self.app.callback(
|
||||
[Output('total-predictions-count', 'children'),
|
||||
Output('pending-predictions-count', 'children'),
|
||||
Output('active-models-count', 'children'),
|
||||
Output('total-rewards-sum', 'children'),
|
||||
Output('prediction-timeline-chart', 'figure'),
|
||||
Output('model-performance-chart', 'figure')],
|
||||
[Input('interval-component', 'n_intervals')]
|
||||
)
|
||||
def update_prediction_tracking(n_intervals):
|
||||
"""Update prediction tracking charts and metrics"""
|
||||
try:
|
||||
if (hasattr(self.orchestrator, 'enhanced_training_system') and
|
||||
self.orchestrator.enhanced_training_system):
|
||||
|
||||
# Get prediction data
|
||||
stats = self.orchestrator.enhanced_training_system.get_model_performance_stats()
|
||||
models = stats.get('models', [])
|
||||
total_active = stats.get('total_active_predictions', 0)
|
||||
|
||||
# Calculate totals
|
||||
total_predictions = sum(m.get('total_predictions', 0) for m in models)
|
||||
total_rewards = sum(m.get('total_reward', 0) for m in models)
|
||||
active_models = len(models)
|
||||
|
||||
# Create timeline chart (simplified)
|
||||
timeline_fig = {
|
||||
'data': [],
|
||||
'layout': {
|
||||
'title': 'Recent Predictions Timeline',
|
||||
'xaxis': {'title': 'Time'},
|
||||
'yaxis': {'title': 'Confidence'},
|
||||
'template': 'plotly_dark',
|
||||
'height': 300,
|
||||
'showlegend': False
|
||||
}
|
||||
}
|
||||
|
||||
# Add empty annotation if no data
|
||||
if not models:
|
||||
timeline_fig['layout']['annotations'] = [{
|
||||
'text': 'No prediction data yet',
|
||||
'xref': 'paper', 'yref': 'paper',
|
||||
'x': 0.5, 'y': 0.5,
|
||||
'showarrow': False,
|
||||
'font': {'size': 16, 'color': 'gray'}
|
||||
}]
|
||||
|
||||
# Create performance chart
|
||||
performance_fig = {
|
||||
'data': [],
|
||||
'layout': {
|
||||
'title': 'Model Performance',
|
||||
'template': 'plotly_dark',
|
||||
'height': 300,
|
||||
'showlegend': True
|
||||
}
|
||||
}
|
||||
|
||||
if models:
|
||||
model_names = [m.get('model_name', 'Unknown') for m in models]
|
||||
accuracies = [m.get('accuracy', 0) * 100 for m in models]
|
||||
rewards = [m.get('total_reward', 0) for m in models]
|
||||
|
||||
# Add accuracy bars
|
||||
performance_fig['data'].append({
|
||||
'x': model_names,
|
||||
'y': accuracies,
|
||||
'type': 'bar',
|
||||
'name': 'Accuracy (%)',
|
||||
'marker': {'color': 'lightblue'}
|
||||
})
|
||||
|
||||
performance_fig['layout']['xaxis'] = {'title': 'Model'}
|
||||
performance_fig['layout']['yaxis'] = {'title': 'Accuracy (%)'}
|
||||
else:
|
||||
performance_fig['layout']['annotations'] = [{
|
||||
'text': 'No model data yet',
|
||||
'xref': 'paper', 'yref': 'paper',
|
||||
'x': 0.5, 'y': 0.5,
|
||||
'showarrow': False,
|
||||
'font': {'size': 16, 'color': 'gray'}
|
||||
}]
|
||||
|
||||
return (
|
||||
str(total_predictions),
|
||||
str(total_active),
|
||||
str(active_models),
|
||||
f"{total_rewards:.1f}",
|
||||
timeline_fig,
|
||||
performance_fig
|
||||
)
|
||||
else:
|
||||
# Training system not available
|
||||
empty_fig = {
|
||||
'data': [],
|
||||
'layout': {
|
||||
'template': 'plotly_dark',
|
||||
'height': 300,
|
||||
'annotations': [{
|
||||
'text': 'Training system not available',
|
||||
'xref': 'paper', 'yref': 'paper',
|
||||
'x': 0.5, 'y': 0.5,
|
||||
'showarrow': False,
|
||||
'font': {'size': 16, 'color': 'red'}
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
return "N/A", "N/A", "N/A", "N/A", empty_fig, empty_fig
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating prediction tracking: {e}")
|
||||
error_fig = {
|
||||
'data': [],
|
||||
'layout': {
|
||||
'template': 'plotly_dark',
|
||||
'height': 300,
|
||||
'annotations': [{
|
||||
'text': f'Error: {str(e)}',
|
||||
'xref': 'paper', 'yref': 'paper',
|
||||
'x': 0.5, 'y': 0.5,
|
||||
'showarrow': False,
|
||||
'font': {'size': 14, 'color': 'red'}
|
||||
}]
|
||||
}
|
||||
}
|
||||
return "Error", "Error", "Error", "Error", error_fig, error_fig
|
||||
|
||||
@self.app.callback(
|
||||
[Output('eth-cob-content', 'children'),
|
||||
Output('btc-cob-content', 'children')],
|
||||
|
||||
Reference in New Issue
Block a user