LIVE CHART WORKS ON ANNOTATE APP

This commit is contained in:
Dobromir Popov
2025-11-22 01:26:25 +02:00
parent 6ad09acc19
commit a1d3d6a865
2 changed files with 169 additions and 27 deletions

View File

@@ -7,7 +7,7 @@ data quality and structure used by training and inference systems.
import logging
from typing import Dict, List, Optional, Tuple
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
import pandas as pd
from pathlib import Path
import pickle
@@ -73,7 +73,11 @@ class HistoricalDataLoader:
elif timeframe == '1m':
current_ttl = timedelta(seconds=5)
if cache_key in self.memory_cache and direction == 'latest':
# For 'after' direction (incremental updates), we should force a refresh if cache is stale
# or simply bypass cache for 1s/1m to ensure we get the absolute latest
bypass_cache = (direction == 'after' and timeframe in ['1s', '1m'])
if cache_key in self.memory_cache and direction == 'latest' and not bypass_cache:
cached_data, cached_time = self.memory_cache[cache_key]
if datetime.now() - cached_time < current_ttl:
# For 1s/1m, we want to return immediately if valid
@@ -83,8 +87,8 @@ class HistoricalDataLoader:
return cached_data
try:
# FORCE refresh for 1s/1m if requesting latest data
force_refresh = (timeframe in ['1s', '1m'] and not start_time and not end_time)
# FORCE refresh for 1s/1m if requesting latest data OR incremental update
force_refresh = (timeframe in ['1s', '1m'] and (bypass_cache or (not start_time and not end_time)))
# Try to get data from DataProvider's cached data first (most efficient)
if hasattr(self.data_provider, 'cached_data'):
with self.data_provider.data_lock:
@@ -403,27 +407,53 @@ class HistoricalDataLoader:
Returns:
Filtered DataFrame
"""
if direction == 'before' and end_time:
# Get candles BEFORE end_time
df = df[df.index < end_time]
# Return the most recent N candles before end_time
df = df.tail(limit)
elif direction == 'after' and start_time:
# Get candles AFTER start_time
df = df[df.index > start_time]
# Return the oldest N candles after start_time
df = df.head(limit)
else:
# Default: filter by range
if start_time:
df = df[df.index >= start_time]
if end_time:
df = df[df.index <= end_time]
# Return most recent candles
if len(df) > limit:
try:
# Ensure df index is datetime and timezone-aware (UTC)
if not isinstance(df.index, pd.DatetimeIndex):
df.index = pd.to_datetime(df.index, utc=True)
elif df.index.tz is None:
df.index = df.index.tz_localize('UTC')
else:
# If already aware but not UTC, convert
if str(df.index.tz) != 'UTC' and str(df.index.tz) != 'datetime.timezone.utc':
df.index = df.index.tz_convert('UTC')
# Ensure start_time/end_time are UTC
if start_time and start_time.tzinfo is None:
start_time = start_time.replace(tzinfo=timezone.utc)
elif start_time:
start_time = start_time.astimezone(timezone.utc)
if end_time and end_time.tzinfo is None:
end_time = end_time.replace(tzinfo=timezone.utc)
elif end_time:
end_time = end_time.astimezone(timezone.utc)
if direction == 'before' and end_time:
# Get candles BEFORE end_time
df = df[df.index < end_time]
# Return the most recent N candles before end_time
df = df.tail(limit)
return df
elif direction == 'after' and start_time:
# Get candles AFTER start_time
df = df[df.index > start_time]
# Return the oldest N candles after start_time
df = df.head(limit)
else:
# Default: filter by range
if start_time:
df = df[df.index >= start_time]
if end_time:
df = df[df.index <= end_time]
# Return most recent candles
if len(df) > limit:
df = df.tail(limit)
return df
except Exception as e:
logger.error(f"Error filtering data: {e}")
# Fallback: return original or empty
return df if not df.empty else pd.DataFrame()
def get_multi_timeframe_data(self, symbol: str,
timeframes: List[str],