wip
This commit is contained in:
@@ -1189,7 +1189,7 @@ class AnnotationDashboard:
|
||||
|
||||
# Add ALL pivot points to the map
|
||||
for pivot in trend_level.pivot_points:
|
||||
ts_str = pivot.timestamp.strftime('%Y-%m-%d %H:%M:%S')
|
||||
ts_str = self._format_timestamp_utc(pivot.timestamp)
|
||||
|
||||
if ts_str not in pivot_map:
|
||||
pivot_map[ts_str] = {'highs': [], 'lows': []}
|
||||
@@ -1226,6 +1226,51 @@ class AnnotationDashboard:
|
||||
logger.error(traceback.format_exc())
|
||||
return {}
|
||||
|
||||
def _format_timestamp_utc(self, ts):
|
||||
"""
|
||||
Format timestamp in ISO format with UTC indicator ('Z' suffix)
|
||||
This ensures frontend JavaScript parses it as UTC, not local time
|
||||
|
||||
Args:
|
||||
ts: pandas Timestamp or datetime object
|
||||
|
||||
Returns:
|
||||
str: ISO format timestamp with 'Z' suffix (e.g., '2025-12-08T21:00:00Z')
|
||||
"""
|
||||
try:
|
||||
# Ensure timestamp is UTC
|
||||
if hasattr(ts, 'tz'):
|
||||
if ts.tz is not None:
|
||||
ts_utc = ts.tz_convert('UTC') if hasattr(ts, 'tz_convert') else ts
|
||||
else:
|
||||
try:
|
||||
ts_utc = ts.tz_localize('UTC') if hasattr(ts, 'tz_localize') else ts
|
||||
except:
|
||||
ts_utc = ts
|
||||
else:
|
||||
ts_utc = ts
|
||||
|
||||
# Format as ISO with 'Z' for UTC
|
||||
if hasattr(ts_utc, 'strftime'):
|
||||
return ts_utc.strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||
else:
|
||||
return str(ts_utc)
|
||||
except Exception as e:
|
||||
logger.debug(f"Error formatting timestamp: {e}")
|
||||
return str(ts)
|
||||
|
||||
def _format_timestamps_utc(self, timestamp_series):
|
||||
"""
|
||||
Format a series of timestamps in ISO format with UTC indicator
|
||||
|
||||
Args:
|
||||
timestamp_series: pandas Index or Series with timestamps
|
||||
|
||||
Returns:
|
||||
list: List of ISO format timestamps with 'Z' suffix
|
||||
"""
|
||||
return [self._format_timestamp_utc(ts) for ts in timestamp_series]
|
||||
|
||||
def _setup_routes(self):
|
||||
"""Setup Flask routes"""
|
||||
|
||||
@@ -1418,7 +1463,7 @@ class AnnotationDashboard:
|
||||
|
||||
chart_data = {
|
||||
timeframe: {
|
||||
'timestamps': df.index.strftime('%Y-%m-%d %H:%M:%S').tolist(),
|
||||
'timestamps': self._format_timestamps_utc(df.index),
|
||||
'open': df['open'].tolist(),
|
||||
'high': df['high'].tolist(),
|
||||
'low': df['low'].tolist(),
|
||||
@@ -1496,7 +1541,7 @@ class AnnotationDashboard:
|
||||
|
||||
# Convert to format suitable for Plotly
|
||||
chart_data[timeframe] = {
|
||||
'timestamps': df.index.strftime('%Y-%m-%d %H:%M:%S').tolist(),
|
||||
'timestamps': self._format_timestamps_utc(df.index),
|
||||
'open': df['open'].tolist(),
|
||||
'high': df['high'].tolist(),
|
||||
'low': df['low'].tolist(),
|
||||
@@ -1766,8 +1811,31 @@ class AnnotationDashboard:
|
||||
# Get pivot markers for this timeframe
|
||||
pivot_markers = self._get_pivot_markers_for_timeframe(symbol, timeframe, df)
|
||||
|
||||
# CRITICAL FIX: Format timestamps in ISO format with UTC indicator
|
||||
# This ensures frontend parses them as UTC, not local time
|
||||
timestamps = []
|
||||
for ts in df.index:
|
||||
# Ensure timestamp is UTC
|
||||
if hasattr(ts, 'tz'):
|
||||
if ts.tz is not None:
|
||||
ts_utc = ts.tz_convert('UTC') if hasattr(ts, 'tz_convert') else ts
|
||||
else:
|
||||
try:
|
||||
ts_utc = ts.tz_localize('UTC') if hasattr(ts, 'tz_localize') else ts
|
||||
except:
|
||||
ts_utc = ts
|
||||
else:
|
||||
ts_utc = ts
|
||||
|
||||
# Format as ISO with 'Z' for UTC: 'YYYY-MM-DDTHH:MM:SSZ'
|
||||
# Plotly handles ISO format correctly
|
||||
if hasattr(ts_utc, 'strftime'):
|
||||
timestamps.append(ts_utc.strftime('%Y-%m-%dT%H:%M:%SZ'))
|
||||
else:
|
||||
timestamps.append(str(ts_utc))
|
||||
|
||||
chart_data[timeframe] = {
|
||||
'timestamps': df.index.strftime('%Y-%m-%d %H:%M:%S').tolist(),
|
||||
'timestamps': timestamps,
|
||||
'open': df['open'].tolist(),
|
||||
'high': df['high'].tolist(),
|
||||
'low': df['low'].tolist(),
|
||||
@@ -2590,6 +2658,30 @@ class AnnotationDashboard:
|
||||
metrics = session['metrics'].copy()
|
||||
break
|
||||
|
||||
# CRITICAL FIX: Include position state and session metrics for UI state restoration
|
||||
position_state = None
|
||||
session_metrics = None
|
||||
|
||||
# Get position state and session metrics from orchestrator if available
|
||||
if self.orchestrator and hasattr(self.orchestrator, 'get_position_state'):
|
||||
try:
|
||||
position_state = self.orchestrator.get_position_state()
|
||||
except:
|
||||
pass
|
||||
|
||||
if self.orchestrator and hasattr(self.orchestrator, 'get_session_metrics'):
|
||||
try:
|
||||
session_metrics = self.orchestrator.get_session_metrics()
|
||||
except:
|
||||
pass
|
||||
|
||||
# Add position state and session metrics to metrics dict
|
||||
if position_state:
|
||||
metrics['position_state'] = position_state
|
||||
if session_metrics:
|
||||
metrics['session_pnl'] = session_metrics.get('total_pnl', 0.0)
|
||||
metrics['session_metrics'] = session_metrics
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'signals': signals,
|
||||
@@ -3106,7 +3198,7 @@ class AnnotationDashboard:
|
||||
if not df_before.empty:
|
||||
recent = df_before.tail(200)
|
||||
market_state['timeframes'][tf] = {
|
||||
'timestamps': recent.index.strftime('%Y-%m-%d %H:%M:%S').tolist(),
|
||||
'timestamps': self._format_timestamps_utc(recent.index),
|
||||
'open': recent['open'].tolist(),
|
||||
'high': recent['high'].tolist(),
|
||||
'low': recent['low'].tolist(),
|
||||
|
||||
Reference in New Issue
Block a user