display time in current TZ
This commit is contained in:
parent
058816ddcd
commit
05f61b5663
181
realtime.py
181
realtime.py
@ -17,6 +17,8 @@ from threading import Thread
|
||||
import requests
|
||||
import os
|
||||
from datetime import datetime, timedelta
|
||||
import pytz
|
||||
import tzlocal
|
||||
|
||||
# Configure logging with more detailed format
|
||||
logging.basicConfig(
|
||||
@ -29,6 +31,50 @@ logging.basicConfig(
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Try to get local timezone, default to Sofia/EET if not available
|
||||
try:
|
||||
local_timezone = tzlocal.get_localzone()
|
||||
# Get timezone name safely
|
||||
try:
|
||||
tz_name = str(local_timezone)
|
||||
# Handle case where it might be zoneinfo.ZoneInfo object instead of pytz timezone
|
||||
if hasattr(local_timezone, 'zone'):
|
||||
tz_name = local_timezone.zone
|
||||
elif hasattr(local_timezone, 'key'):
|
||||
tz_name = local_timezone.key
|
||||
else:
|
||||
tz_name = str(local_timezone)
|
||||
except:
|
||||
tz_name = "Local"
|
||||
logger.info(f"Detected local timezone: {local_timezone} ({tz_name})")
|
||||
except Exception as e:
|
||||
logger.warning(f"Could not detect local timezone: {str(e)}. Defaulting to Sofia/EET")
|
||||
local_timezone = pytz.timezone('Europe/Sofia')
|
||||
tz_name = "Europe/Sofia"
|
||||
|
||||
def convert_to_local_time(timestamp):
|
||||
"""Convert timestamp to local timezone"""
|
||||
try:
|
||||
if isinstance(timestamp, pd.Timestamp):
|
||||
dt = timestamp.to_pydatetime()
|
||||
elif isinstance(timestamp, np.datetime64):
|
||||
dt = pd.Timestamp(timestamp).to_pydatetime()
|
||||
elif isinstance(timestamp, str):
|
||||
dt = pd.to_datetime(timestamp).to_pydatetime()
|
||||
else:
|
||||
dt = timestamp
|
||||
|
||||
# If datetime is naive (no timezone), assume it's UTC
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=pytz.UTC)
|
||||
|
||||
# Convert to local timezone
|
||||
local_dt = dt.astimezone(local_timezone)
|
||||
return local_dt
|
||||
except Exception as e:
|
||||
logger.error(f"Error converting timestamp to local time: {str(e)}")
|
||||
return timestamp
|
||||
|
||||
class TradeTickStorage:
|
||||
"""Store and manage raw trade ticks for display and candle formation"""
|
||||
def __init__(self, max_age_seconds: int = 1800): # 30 minutes by default
|
||||
@ -1110,10 +1156,19 @@ class RealTimeChart:
|
||||
|
||||
logger.debug(f"Displaying {len(display_df)} candles in main chart")
|
||||
|
||||
# Convert timestamps to local time for display
|
||||
display_df = display_df.copy()
|
||||
try:
|
||||
display_df['local_time'] = display_df['timestamp'].apply(convert_to_local_time)
|
||||
logger.debug(f"Converted timestamps to local time ({local_timezone})")
|
||||
except Exception as e:
|
||||
logger.error(f"Error converting timestamps to local time: {str(e)}")
|
||||
display_df['local_time'] = display_df['timestamp']
|
||||
|
||||
# Add candlestick chart
|
||||
fig.add_trace(
|
||||
go.Candlestick(
|
||||
x=display_df['timestamp'],
|
||||
x=display_df['local_time'], # Use local time for display
|
||||
open=display_df['open'],
|
||||
high=display_df['high'],
|
||||
low=display_df['low'],
|
||||
@ -1131,7 +1186,7 @@ class RealTimeChart:
|
||||
|
||||
fig.add_trace(
|
||||
go.Bar(
|
||||
x=display_df['timestamp'],
|
||||
x=display_df['local_time'], # Use local time for display
|
||||
y=display_df['volume'],
|
||||
name='Volume',
|
||||
marker_color=colors
|
||||
@ -1141,21 +1196,30 @@ class RealTimeChart:
|
||||
|
||||
# Add latest price line from the candlestick data
|
||||
latest_price = display_df['close'].iloc[-1]
|
||||
latest_time = display_df['local_time'].iloc[-1]
|
||||
earliest_time = display_df['local_time'].iloc[0]
|
||||
|
||||
fig.add_shape(
|
||||
type="line",
|
||||
x0=display_df['timestamp'].min(),
|
||||
x0=earliest_time,
|
||||
y0=latest_price,
|
||||
x1=display_df['timestamp'].max(),
|
||||
x1=latest_time,
|
||||
y1=latest_price,
|
||||
line=dict(color="yellow", width=1, dash="dash"),
|
||||
row=1, col=1
|
||||
)
|
||||
|
||||
# Format the last update time in local timezone
|
||||
try:
|
||||
last_update_time = latest_time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
except:
|
||||
last_update_time = datetime.now().astimezone(local_timezone).strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
# Annotation for last candle close price
|
||||
fig.add_annotation(
|
||||
x=display_df['timestamp'].max(),
|
||||
x=latest_time,
|
||||
y=latest_price,
|
||||
text=f"{latest_price:.2f}",
|
||||
text=f"{latest_price:.2f} ({last_update_time})",
|
||||
showarrow=False,
|
||||
font=dict(size=14, color="yellow"),
|
||||
xshift=50,
|
||||
@ -1167,19 +1231,22 @@ class RealTimeChart:
|
||||
# Add current price line
|
||||
fig.add_shape(
|
||||
type="line",
|
||||
x0=display_df['timestamp'].min(),
|
||||
x0=earliest_time,
|
||||
y0=current_price,
|
||||
x1=display_df['timestamp'].max(),
|
||||
x1=latest_time,
|
||||
y1=current_price,
|
||||
line=dict(color="cyan", width=1, dash="dot"),
|
||||
row=1, col=1
|
||||
)
|
||||
|
||||
# Format current time in local timezone
|
||||
current_time_str = datetime.now().astimezone(local_timezone).strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
# Add current price annotation
|
||||
fig.add_annotation(
|
||||
x=display_df['timestamp'].max(),
|
||||
x=latest_time,
|
||||
y=current_price,
|
||||
text=f"Current: {current_price:.2f}",
|
||||
text=f"Current: {current_price:.2f} ({current_time_str})",
|
||||
showarrow=False,
|
||||
font=dict(size=14, color="cyan"),
|
||||
xshift=50,
|
||||
@ -1221,13 +1288,21 @@ class RealTimeChart:
|
||||
if len(ohlcv_df) > 100:
|
||||
ohlcv_df = ohlcv_df.tail(100)
|
||||
|
||||
# Convert to local time
|
||||
ohlcv_display_df = ohlcv_df.copy()
|
||||
try:
|
||||
ohlcv_display_df['local_time'] = ohlcv_df['timestamp'].apply(convert_to_local_time)
|
||||
except Exception as e:
|
||||
logger.error(f"Error converting {interval_key} timestamps to local time: {str(e)}")
|
||||
ohlcv_display_df['local_time'] = ohlcv_df['timestamp']
|
||||
|
||||
fig.add_trace(
|
||||
go.Candlestick(
|
||||
x=ohlcv_df['timestamp'],
|
||||
open=ohlcv_df['open'],
|
||||
high=ohlcv_df['high'],
|
||||
low=ohlcv_df['low'],
|
||||
close=ohlcv_df['close'],
|
||||
x=ohlcv_display_df['local_time'],
|
||||
open=ohlcv_display_df['open'],
|
||||
high=ohlcv_display_df['high'],
|
||||
low=ohlcv_display_df['low'],
|
||||
close=ohlcv_display_df['close'],
|
||||
name=f'{label}',
|
||||
increasing_line_color='#33CC33',
|
||||
decreasing_line_color='#FF4136',
|
||||
@ -1237,23 +1312,33 @@ class RealTimeChart:
|
||||
)
|
||||
|
||||
# Add latest price line
|
||||
latest_timeframe_price = ohlcv_df['close'].iloc[-1] if len(ohlcv_df) > 0 else None
|
||||
latest_timeframe_price = ohlcv_display_df['close'].iloc[-1] if len(ohlcv_display_df) > 0 else None
|
||||
if latest_timeframe_price:
|
||||
# Get first and last timestamps
|
||||
earliest_tf_time = ohlcv_display_df['local_time'].iloc[0]
|
||||
latest_tf_time = ohlcv_display_df['local_time'].iloc[-1]
|
||||
|
||||
fig.add_shape(
|
||||
type="line",
|
||||
x0=ohlcv_df['timestamp'].min(),
|
||||
x0=earliest_tf_time,
|
||||
y0=latest_timeframe_price,
|
||||
x1=ohlcv_df['timestamp'].max(),
|
||||
x1=latest_tf_time,
|
||||
y1=latest_timeframe_price,
|
||||
line=dict(color="yellow", width=1, dash="dash"),
|
||||
row=row_idx, col=1
|
||||
)
|
||||
|
||||
# Get formatted time
|
||||
try:
|
||||
update_time = latest_tf_time.strftime('%Y-%m-%d %H:%M')
|
||||
except:
|
||||
update_time = ""
|
||||
|
||||
# Add price annotation
|
||||
fig.add_annotation(
|
||||
x=ohlcv_df['timestamp'].max(),
|
||||
x=latest_tf_time,
|
||||
y=latest_timeframe_price,
|
||||
text=f"{latest_timeframe_price:.2f}",
|
||||
text=f"{latest_timeframe_price:.2f} ({update_time})",
|
||||
showarrow=False,
|
||||
font=dict(size=12, color="yellow"),
|
||||
xshift=50,
|
||||
@ -1279,13 +1364,21 @@ class RealTimeChart:
|
||||
if len(ohlcv_df) > 100:
|
||||
ohlcv_df = ohlcv_df.tail(100)
|
||||
|
||||
# Convert to local time
|
||||
ohlcv_display_df = ohlcv_df.copy()
|
||||
try:
|
||||
ohlcv_display_df['local_time'] = ohlcv_df['timestamp'].apply(convert_to_local_time)
|
||||
except Exception as e:
|
||||
logger.error(f"Error converting {interval_key} timestamps to local time: {str(e)}")
|
||||
ohlcv_display_df['local_time'] = ohlcv_df['timestamp']
|
||||
|
||||
fig.add_trace(
|
||||
go.Candlestick(
|
||||
x=ohlcv_df['timestamp'],
|
||||
open=ohlcv_df['open'],
|
||||
high=ohlcv_df['high'],
|
||||
low=ohlcv_df['low'],
|
||||
close=ohlcv_df['close'],
|
||||
x=ohlcv_display_df['local_time'],
|
||||
open=ohlcv_display_df['open'],
|
||||
high=ohlcv_display_df['high'],
|
||||
low=ohlcv_display_df['low'],
|
||||
close=ohlcv_display_df['close'],
|
||||
name=f'{label}',
|
||||
increasing_line_color='#33CC33',
|
||||
decreasing_line_color='#FF4136',
|
||||
@ -1293,6 +1386,40 @@ class RealTimeChart:
|
||||
),
|
||||
row=row_idx, col=1
|
||||
)
|
||||
|
||||
# Add latest price line
|
||||
latest_timeframe_price = ohlcv_display_df['close'].iloc[-1] if len(ohlcv_display_df) > 0 else None
|
||||
if latest_timeframe_price:
|
||||
# Get first and last timestamps
|
||||
earliest_tf_time = ohlcv_display_df['local_time'].iloc[0]
|
||||
latest_tf_time = ohlcv_display_df['local_time'].iloc[-1]
|
||||
|
||||
fig.add_shape(
|
||||
type="line",
|
||||
x0=earliest_tf_time,
|
||||
y0=latest_timeframe_price,
|
||||
x1=latest_tf_time,
|
||||
y1=latest_timeframe_price,
|
||||
line=dict(color="yellow", width=1, dash="dash"),
|
||||
row=row_idx, col=1
|
||||
)
|
||||
|
||||
# Get formatted time
|
||||
try:
|
||||
update_time = latest_tf_time.strftime('%Y-%m-%d %H:%M')
|
||||
except:
|
||||
update_time = ""
|
||||
|
||||
# Add price annotation
|
||||
fig.add_annotation(
|
||||
x=latest_tf_time,
|
||||
y=latest_timeframe_price,
|
||||
text=f"{latest_timeframe_price:.2f} ({update_time})",
|
||||
showarrow=False,
|
||||
font=dict(size=12, color="yellow"),
|
||||
xshift=50,
|
||||
row=row_idx, col=1
|
||||
)
|
||||
|
||||
# Add a message to the empty main chart
|
||||
fig.add_annotation(
|
||||
@ -1317,6 +1444,10 @@ class RealTimeChart:
|
||||
# Build info box text with all the statistics
|
||||
info_lines = [f"<b>{self.symbol}</b>"]
|
||||
|
||||
# Add current time in local timezone
|
||||
current_local_time = datetime.now().astimezone(local_timezone)
|
||||
info_lines.append(f"Time: {current_local_time.strftime('%Y-%m-%d %H:%M:%S')} ({tz_name})")
|
||||
|
||||
# Add current price if available
|
||||
if current_price:
|
||||
info_lines.append(f"Current: <b>{current_price:.2f}</b> USDT")
|
||||
|
Loading…
x
Reference in New Issue
Block a user