This commit is contained in:
Dobromir Popov
2025-05-24 01:23:14 +03:00
parent 0c445435d0
commit d79e73d816
3 changed files with 328 additions and 6 deletions

View File

@ -1038,8 +1038,23 @@ class TickStorage:
try:
# Only save the latest 5000 ticks to avoid giant files
ticks_to_save = self.ticks[-5000:] if len(self.ticks) > 5000 else self.ticks
# Convert pandas Timestamps to ISO strings for JSON serialization
serializable_ticks = []
for tick in ticks_to_save:
serializable_tick = tick.copy()
if isinstance(tick['timestamp'], pd.Timestamp):
serializable_tick['timestamp'] = tick['timestamp'].isoformat()
elif hasattr(tick['timestamp'], 'isoformat'):
serializable_tick['timestamp'] = tick['timestamp'].isoformat()
else:
# Keep as is if it's already a string or number
serializable_tick['timestamp'] = tick['timestamp']
serializable_ticks.append(serializable_tick)
with open(self.cache_path, 'w') as f:
json.dump(ticks_to_save, f)
json.dump(serializable_ticks, f)
logger.debug(f"Saved {len(serializable_ticks)} ticks to cache")
except Exception as e:
logger.error(f"Error saving ticks to cache: {e}")
@ -1057,7 +1072,22 @@ class TickStorage:
cached_ticks = json.load(f)
if cached_ticks:
self.ticks = cached_ticks
# Convert ISO strings back to pandas Timestamps
processed_ticks = []
for tick in cached_ticks:
processed_tick = tick.copy()
if isinstance(tick['timestamp'], str):
try:
processed_tick['timestamp'] = pd.Timestamp(tick['timestamp'])
except:
# If parsing fails, use current time
processed_tick['timestamp'] = pd.Timestamp.now()
else:
# Convert to pandas Timestamp if it's a number (milliseconds)
processed_tick['timestamp'] = pd.Timestamp(tick['timestamp'], unit='ms')
processed_ticks.append(processed_tick)
self.ticks = processed_ticks
logger.info(f"Loaded {len(cached_ticks)} ticks from cache")
return True
except Exception as e:
@ -1088,11 +1118,20 @@ class TickStorage:
else:
logger.error("Invalid tick: must provide either a tick dict or price")
return
# Ensure timestamp is a pandas Timestamp
if not isinstance(timestamp, pd.Timestamp):
if isinstance(timestamp, (int, float)):
# Assume it's milliseconds
timestamp = pd.Timestamp(timestamp, unit='ms')
else:
# Try to parse as string or datetime
timestamp = pd.Timestamp(timestamp)
# Create tick object
# Create tick object with consistent pandas Timestamp
tick_obj = {
'price': price,
'quantity': volume if volume is not None else 0,
'price': float(price),
'quantity': float(volume) if volume is not None else 0.0,
'timestamp': timestamp
}
@ -1473,7 +1512,13 @@ class TickStorage:
"""Try to save ticks to cache periodically"""
# Only save to cache every 100 ticks to avoid excessive disk I/O
if len(self.ticks) % 100 == 0:
self._save_to_cache()
try:
self._save_to_cache()
except Exception as e:
# Don't spam logs with cache errors, just log once every 1000 ticks
if len(self.ticks) % 1000 == 0:
logger.warning(f"Cache save failed at {len(self.ticks)} ticks: {str(e)}")
pass # Continue even if cache fails
class Position:
"""Represents a trading position"""