218 lines
6.9 KiB
Python
218 lines
6.9 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Simple Dashboard Runner - Fixed version for testing
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import logging
|
|
import time
|
|
import threading
|
|
from pathlib import Path
|
|
|
|
# Fix OpenMP library conflicts
|
|
os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'
|
|
os.environ['OMP_NUM_THREADS'] = '4'
|
|
|
|
# Fix matplotlib backend
|
|
import matplotlib
|
|
matplotlib.use('Agg')
|
|
|
|
# Add project root to path
|
|
project_root = Path(__file__).parent
|
|
sys.path.insert(0, str(project_root))
|
|
|
|
# Setup logging
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def create_simple_dashboard():
|
|
"""Create a simple working dashboard"""
|
|
try:
|
|
import dash
|
|
from dash import html, dcc, Input, Output
|
|
import plotly.graph_objs as go
|
|
import pandas as pd
|
|
import numpy as np
|
|
from datetime import datetime, timedelta
|
|
|
|
# Create Dash app
|
|
app = dash.Dash(__name__)
|
|
|
|
# Simple layout
|
|
app.layout = html.Div([
|
|
html.H1("Trading System Dashboard", style={'textAlign': 'center', 'color': '#2c3e50'}),
|
|
|
|
html.Div([
|
|
html.Div([
|
|
html.H3("System Status", style={'color': '#27ae60'}),
|
|
html.P(id='system-status', children="System: RUNNING", style={'fontSize': '18px'}),
|
|
html.P(id='current-time', children=f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"),
|
|
], style={'width': '48%', 'display': 'inline-block', 'padding': '20px'}),
|
|
|
|
html.Div([
|
|
html.H3("Trading Stats", style={'color': '#3498db'}),
|
|
html.P("Total Trades: 0"),
|
|
html.P("Success Rate: 0%"),
|
|
html.P("Current PnL: $0.00"),
|
|
], style={'width': '48%', 'display': 'inline-block', 'padding': '20px'}),
|
|
]),
|
|
|
|
html.Div([
|
|
dcc.Graph(id='price-chart'),
|
|
], style={'padding': '20px'}),
|
|
|
|
html.Div([
|
|
dcc.Graph(id='performance-chart'),
|
|
], style={'padding': '20px'}),
|
|
|
|
# Auto-refresh component
|
|
dcc.Interval(
|
|
id='interval-component',
|
|
interval=5000, # Update every 5 seconds
|
|
n_intervals=0
|
|
)
|
|
])
|
|
|
|
# Callback for updating time
|
|
@app.callback(
|
|
Output('current-time', 'children'),
|
|
Input('interval-component', 'n_intervals')
|
|
)
|
|
def update_time(n):
|
|
return f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
|
|
|
|
# Callback for price chart
|
|
@app.callback(
|
|
Output('price-chart', 'figure'),
|
|
Input('interval-component', 'n_intervals')
|
|
)
|
|
def update_price_chart(n):
|
|
# Generate sample data
|
|
dates = pd.date_range(start=datetime.now() - timedelta(hours=24),
|
|
end=datetime.now(), freq='1H')
|
|
prices = 3000 + np.cumsum(np.random.randn(len(dates)) * 10)
|
|
|
|
fig = go.Figure()
|
|
fig.add_trace(go.Scatter(
|
|
x=dates,
|
|
y=prices,
|
|
mode='lines',
|
|
name='ETH/USDT',
|
|
line=dict(color='#3498db', width=2)
|
|
))
|
|
|
|
fig.update_layout(
|
|
title='ETH/USDT Price Chart (24H)',
|
|
xaxis_title='Time',
|
|
yaxis_title='Price (USD)',
|
|
template='plotly_white',
|
|
height=400
|
|
)
|
|
|
|
return fig
|
|
|
|
# Callback for performance chart
|
|
@app.callback(
|
|
Output('performance-chart', 'figure'),
|
|
Input('interval-component', 'n_intervals')
|
|
)
|
|
def update_performance_chart(n):
|
|
# Generate sample performance data
|
|
dates = pd.date_range(start=datetime.now() - timedelta(days=7),
|
|
end=datetime.now(), freq='1D')
|
|
performance = np.cumsum(np.random.randn(len(dates)) * 0.02) * 100
|
|
|
|
fig = go.Figure()
|
|
fig.add_trace(go.Scatter(
|
|
x=dates,
|
|
y=performance,
|
|
mode='lines+markers',
|
|
name='Portfolio Performance',
|
|
line=dict(color='#27ae60', width=3),
|
|
marker=dict(size=6)
|
|
))
|
|
|
|
fig.update_layout(
|
|
title='Portfolio Performance (7 Days)',
|
|
xaxis_title='Date',
|
|
yaxis_title='Performance (%)',
|
|
template='plotly_white',
|
|
height=400
|
|
)
|
|
|
|
return fig
|
|
|
|
return app
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error creating dashboard: {e}")
|
|
import traceback
|
|
logger.error(traceback.format_exc())
|
|
return None
|
|
|
|
def test_data_provider():
|
|
"""Test data provider in background"""
|
|
try:
|
|
from core.data_provider import DataProvider
|
|
from core.api_rate_limiter import get_rate_limiter
|
|
|
|
logger.info("Testing data provider...")
|
|
|
|
# Create data provider
|
|
data_provider = DataProvider(
|
|
symbols=['ETH/USDT'],
|
|
timeframes=['1m', '5m']
|
|
)
|
|
|
|
# Test getting data
|
|
df = data_provider.get_historical_data('ETH/USDT', '1m', limit=10)
|
|
if df is not None and len(df) > 0:
|
|
logger.info(f"✓ Data provider working: {len(df)} candles retrieved")
|
|
else:
|
|
logger.warning("⚠ Data provider returned no data (rate limiting)")
|
|
|
|
# Test rate limiter status
|
|
rate_limiter = get_rate_limiter()
|
|
status = rate_limiter.get_all_endpoint_status()
|
|
logger.info(f"Rate limiter status: {status}")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Data provider test error: {e}")
|
|
|
|
def main():
|
|
"""Main function"""
|
|
logger.info("=" * 60)
|
|
logger.info("SIMPLE DASHBOARD RUNNER - TESTING SYSTEM")
|
|
logger.info("=" * 60)
|
|
|
|
# Test data provider in background
|
|
data_thread = threading.Thread(target=test_data_provider, daemon=True)
|
|
data_thread.start()
|
|
|
|
# Create and run dashboard
|
|
app = create_simple_dashboard()
|
|
if app is None:
|
|
logger.error("Failed to create dashboard")
|
|
return
|
|
|
|
try:
|
|
logger.info("Starting dashboard server...")
|
|
logger.info("Dashboard URL: http://127.0.0.1:8050")
|
|
logger.info("Press Ctrl+C to stop")
|
|
|
|
# Run the dashboard
|
|
app.run(debug=False, host='127.0.0.1', port=8050, use_reloader=False)
|
|
|
|
except KeyboardInterrupt:
|
|
logger.info("Dashboard stopped by user")
|
|
except Exception as e:
|
|
logger.error(f"Dashboard error: {e}")
|
|
import traceback
|
|
logger.error(traceback.format_exc())
|
|
|
|
if __name__ == "__main__":
|
|
main() |