fixes
This commit is contained in:
@ -1038,8 +1038,23 @@ class TickStorage:
|
|||||||
try:
|
try:
|
||||||
# Only save the latest 5000 ticks to avoid giant files
|
# Only save the latest 5000 ticks to avoid giant files
|
||||||
ticks_to_save = self.ticks[-5000:] if len(self.ticks) > 5000 else self.ticks
|
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:
|
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:
|
except Exception as e:
|
||||||
logger.error(f"Error saving ticks to cache: {e}")
|
logger.error(f"Error saving ticks to cache: {e}")
|
||||||
|
|
||||||
@ -1057,7 +1072,22 @@ class TickStorage:
|
|||||||
cached_ticks = json.load(f)
|
cached_ticks = json.load(f)
|
||||||
|
|
||||||
if cached_ticks:
|
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")
|
logger.info(f"Loaded {len(cached_ticks)} ticks from cache")
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -1088,11 +1118,20 @@ class TickStorage:
|
|||||||
else:
|
else:
|
||||||
logger.error("Invalid tick: must provide either a tick dict or price")
|
logger.error("Invalid tick: must provide either a tick dict or price")
|
||||||
return
|
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 = {
|
tick_obj = {
|
||||||
'price': price,
|
'price': float(price),
|
||||||
'quantity': volume if volume is not None else 0,
|
'quantity': float(volume) if volume is not None else 0.0,
|
||||||
'timestamp': timestamp
|
'timestamp': timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1473,7 +1512,13 @@ class TickStorage:
|
|||||||
"""Try to save ticks to cache periodically"""
|
"""Try to save ticks to cache periodically"""
|
||||||
# Only save to cache every 100 ticks to avoid excessive disk I/O
|
# Only save to cache every 100 ticks to avoid excessive disk I/O
|
||||||
if len(self.ticks) % 100 == 0:
|
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:
|
class Position:
|
||||||
"""Represents a trading position"""
|
"""Represents a trading position"""
|
||||||
|
@ -696978,3 +696978,150 @@ ade'}
|
|||||||
2025-05-24 01:14:40,456 - INFO - [test_chart_data.py:133] - ============================================================
|
2025-05-24 01:14:40,456 - INFO - [test_chart_data.py:133] - ============================================================
|
||||||
2025-05-24 01:14:40,459 - INFO - [test_chart_data.py:142] -
|
2025-05-24 01:14:40,459 - INFO - [test_chart_data.py:142] -
|
||||||
Passed: 3/3 tests
|
Passed: 3/3 tests
|
||||||
|
2025-05-24 01:21:06,330 - INFO - [dataprovider_realtime.py:978] - Detected local timezone: Europe/Kiev (Europe/Kiev)
|
||||||
|
2025-05-24 01:21:06,770 - INFO - [test_chart_data.py:111] - ============================================================
|
||||||
|
2025-05-24 01:21:06,772 - INFO - [test_chart_data.py:122] - ----------------------------------------
|
||||||
|
2025-05-24 01:21:06,772 - INFO - [test_chart_data.py:21] - Testing Binance historical data fetch...
|
||||||
|
2025-05-24 01:21:06,788 - INFO - [dataprovider_realtime.py:337] - Loaded 1000 candles from cache: F:\projects\gogo2\cache\ETHUSDT_1m_candles.csv
|
||||||
|
2025-05-24 01:21:08,497 - INFO - [dataprovider_realtime.py:348] - Saved 100 candles to cache: F:\projects\gogo2\cache\ETHUSDT_1m_candles.csv
|
||||||
|
2025-05-24 01:21:08,497 - INFO - [dataprovider_realtime.py:305] - Fetched 100 candles for ETH/USDT (1m)
|
||||||
|
2025-05-24 01:21:08,497 - INFO - [test_chart_data.py:31] - Latest price: $2553.99
|
||||||
|
2025-05-24 01:21:08,497 - INFO - [test_chart_data.py:32] - Date range: 2025-05-23 20:42:00 to 2025-05-23 22:21:00
|
||||||
|
2025-05-24 01:21:08,500 - INFO - [test_chart_data.py:122] - ----------------------------------------
|
||||||
|
2025-05-24 01:21:08,500 - INFO - [test_chart_data.py:44] - Testing TickStorage data loading...
|
||||||
|
2025-05-24 01:21:08,500 - INFO - [dataprovider_realtime.py:1027] - Creating new tick storage for ETH/USDT with timeframes ['1s', '1m', '5m', '1h']
|
||||||
|
2025-05-24 01:21:08,500 - INFO - [dataprovider_realtime.py:1028] - Cache directory: F:\projects\gogo2\cache\ETHUSDT
|
||||||
|
2025-05-24 01:21:08,500 - INFO - [dataprovider_realtime.py:1029] - Cache file: F:\projects\gogo2\cache\ETHUSDT\ETHUSDT_ticks.json
|
||||||
|
2025-05-24 01:21:08,500 - INFO - [dataprovider_realtime.py:1034] - TickStorage: TimescaleDB integration is DISABLED for ETH/USDT
|
||||||
|
2025-05-24 01:21:08,500 - INFO - [dataprovider_realtime.py:1329] - Starting historical data load for ETH/USDT with limit 100
|
||||||
|
2025-05-24 01:21:08,500 - INFO - [dataprovider_realtime.py:1337] - Attempting to load from cache...
|
||||||
|
2025-05-24 01:21:08,508 - ERROR - [dataprovider_realtime.py:1094] - Error loading ticks from cache: Expecting value: line 1 column 53 (char 52)
|
||||||
|
2025-05-24 01:21:08,509 - INFO - [dataprovider_realtime.py:1342] - No valid cache data found
|
||||||
|
2025-05-24 01:21:08,509 - INFO - [dataprovider_realtime.py:1366] - TimescaleDB not available or disabled
|
||||||
|
2025-05-24 01:21:08,509 - INFO - [dataprovider_realtime.py:1370] - Loading data from Binance API...
|
||||||
|
2025-05-24 01:21:08,509 - INFO - [dataprovider_realtime.py:1379] - Fetching 1m candles for ETH/USDT...
|
||||||
|
2025-05-24 01:21:08,519 - INFO - [dataprovider_realtime.py:337] - Loaded 100 candles from cache: F:\projects\gogo2\cache\ETHUSDT_1m_candles.csv
|
||||||
|
2025-05-24 01:21:09,696 - INFO - [dataprovider_realtime.py:348] - Saved 100 candles to cache: F:\projects\gogo2\cache\ETHUSDT_1m_candles.csv
|
||||||
|
2025-05-24 01:21:09,696 - INFO - [dataprovider_realtime.py:305] - Fetched 100 candles for ETH/USDT (1m)
|
||||||
|
2025-05-24 01:21:09,696 - INFO - [dataprovider_realtime.py:1382] - Loaded 100 1m candles from Binance API
|
||||||
|
2025-05-24 01:21:09,696 - INFO - [dataprovider_realtime.py:1379] - Fetching 5m candles for ETH/USDT...
|
||||||
|
2025-05-24 01:21:09,713 - INFO - [dataprovider_realtime.py:337] - Loaded 1000 candles from cache: F:\projects\gogo2\cache\ETHUSDT_5m_candles.csv
|
||||||
|
2025-05-24 01:21:09,713 - INFO - [dataprovider_realtime.py:265] - Using cached historical data for ETH/USDT (5m)
|
||||||
|
2025-05-24 01:21:09,714 - INFO - [dataprovider_realtime.py:1382] - Loaded 1000 5m candles from Binance API
|
||||||
|
2025-05-24 01:21:09,739 - INFO - [dataprovider_realtime.py:1379] - Fetching 1h candles for ETH/USDT...
|
||||||
|
2025-05-24 01:21:09,750 - INFO - [dataprovider_realtime.py:337] - Loaded 1000 candles from cache: F:\projects\gogo2\cache\ETHUSDT_1h_candles.csv
|
||||||
|
2025-05-24 01:21:09,750 - INFO - [dataprovider_realtime.py:265] - Using cached historical data for ETH/USDT (1h)
|
||||||
|
2025-05-24 01:21:09,750 - INFO - [dataprovider_realtime.py:1382] - Loaded 1000 1h candles from Binance API
|
||||||
|
2025-05-24 01:21:09,769 - INFO - [dataprovider_realtime.py:1410] - Successfully loaded 3 timeframes from Binance API
|
||||||
|
2025-05-24 01:21:09,776 - INFO - [dataprovider_realtime.py:1414] - Loading 1s candles...
|
||||||
|
2025-05-24 01:21:09,776 - INFO - [dataprovider_realtime.py:333] - Using recent 1s cache (age: 7.5 minutes)
|
||||||
|
2025-05-24 01:21:09,776 - INFO - [dataprovider_realtime.py:337] - Loaded 300 candles from cache: F:\projects\gogo2\cache\ETHUSDT_1s_candles.csv
|
||||||
|
2025-05-24 01:21:09,779 - INFO - [dataprovider_realtime.py:265] - Using cached historical data for ETH/USDT (1s)
|
||||||
|
2025-05-24 01:21:09,780 - INFO - [dataprovider_realtime.py:1419] - Loaded 300 recent 1s candles from Binance API
|
||||||
|
2025-05-24 01:21:09,787 - INFO - [dataprovider_realtime.py:1505] - Final 1s candle count: 300
|
||||||
|
2025-05-24 01:21:09,787 - INFO - [dataprovider_realtime.py:1505] - Final 1m candle count: 100
|
||||||
|
2025-05-24 01:21:09,787 - INFO - [dataprovider_realtime.py:1505] - Final 5m candle count: 1000
|
||||||
|
2025-05-24 01:21:09,787 - INFO - [dataprovider_realtime.py:1505] - Final 1h candle count: 1000
|
||||||
|
2025-05-24 01:21:09,787 - INFO - [dataprovider_realtime.py:1508] - Historical data loading completed. Has data: True
|
||||||
|
2025-05-24 01:21:09,789 - INFO - [test_chart_data.py:59] - 1s: 300 candles
|
||||||
|
2025-05-24 01:21:09,789 - INFO - [test_chart_data.py:63] - Latest 1s: 2025-05-23 22:13:36 - $2549.36
|
||||||
|
2025-05-24 01:21:09,789 - INFO - [test_chart_data.py:59] - 1m: 100 candles
|
||||||
|
2025-05-24 01:21:09,790 - INFO - [test_chart_data.py:63] - Latest 1m: 2025-05-23 22:21:00 - $2554.89
|
||||||
|
2025-05-24 01:21:09,790 - INFO - [test_chart_data.py:59] - 5m: 1000 candles
|
||||||
|
2025-05-24 01:21:09,790 - INFO - [test_chart_data.py:63] - Latest 5m: 2025-05-23 22:15:00 - $2550.60
|
||||||
|
2025-05-24 01:21:09,790 - INFO - [test_chart_data.py:59] - 1h: 1000 candles
|
||||||
|
2025-05-24 01:21:09,790 - INFO - [test_chart_data.py:63] - Latest 1h: 2025-05-23 22:00:00 - $2550.79
|
||||||
|
2025-05-24 01:21:09,792 - INFO - [test_chart_data.py:122] - ----------------------------------------
|
||||||
|
2025-05-24 01:21:09,792 - INFO - [test_chart_data.py:78] - Testing RealTimeChart initialization...
|
||||||
|
2025-05-24 01:21:09,792 - INFO - [dataprovider_realtime.py:1027] - Creating new tick storage for ETH/USDT with timeframes ['1s', '1m', '5m', '15m', '1h', '4h', '1d']
|
||||||
|
2025-05-24 01:21:09,793 - INFO - [dataprovider_realtime.py:1028] - Cache directory: F:\projects\gogo2\cache\ETHUSDT
|
||||||
|
2025-05-24 01:21:09,793 - INFO - [dataprovider_realtime.py:1029] - Cache file: F:\projects\gogo2\cache\ETHUSDT\ETHUSDT_ticks.json
|
||||||
|
2025-05-24 01:21:09,793 - INFO - [dataprovider_realtime.py:1685] - Loading historical data for ETH/USDT during chart initialization
|
||||||
|
2025-05-24 01:21:09,793 - INFO - [dataprovider_realtime.py:1329] - Starting historical data load for ETH/USDT with limit 1000
|
||||||
|
2025-05-24 01:21:09,793 - INFO - [dataprovider_realtime.py:1337] - Attempting to load from cache...
|
||||||
|
2025-05-24 01:21:09,794 - ERROR - [dataprovider_realtime.py:1094] - Error loading ticks from cache: Expecting value: line 1 column 53 (char 52)
|
||||||
|
2025-05-24 01:21:09,794 - INFO - [dataprovider_realtime.py:1342] - No valid cache data found
|
||||||
|
2025-05-24 01:21:09,794 - INFO - [dataprovider_realtime.py:1366] - TimescaleDB not available or disabled
|
||||||
|
2025-05-24 01:21:09,794 - INFO - [dataprovider_realtime.py:1370] - Loading data from Binance API...
|
||||||
|
2025-05-24 01:21:09,794 - INFO - [dataprovider_realtime.py:1379] - Fetching 1m candles for ETH/USDT...
|
||||||
|
2025-05-24 01:21:09,806 - INFO - [dataprovider_realtime.py:337] - Loaded 100 candles from cache: F:\projects\gogo2\cache\ETHUSDT_1m_candles.csv
|
||||||
|
2025-05-24 01:21:12,389 - INFO - [dataprovider_realtime.py:348] - Saved 1000 candles to cache: F:\projects\gogo2\cache\ETHUSDT_1m_candles.csv
|
||||||
|
2025-05-24 01:21:12,389 - INFO - [dataprovider_realtime.py:305] - Fetched 1000 candles for ETH/USDT (1m)
|
||||||
|
2025-05-24 01:21:12,389 - INFO - [dataprovider_realtime.py:1382] - Loaded 1000 1m candles from Binance API
|
||||||
|
2025-05-24 01:21:12,415 - INFO - [dataprovider_realtime.py:1379] - Fetching 5m candles for ETH/USDT...
|
||||||
|
2025-05-24 01:21:12,420 - INFO - [dataprovider_realtime.py:337] - Loaded 1000 candles from cache: F:\projects\gogo2\cache\ETHUSDT_5m_candles.csv
|
||||||
|
2025-05-24 01:21:12,420 - INFO - [dataprovider_realtime.py:265] - Using cached historical data for ETH/USDT (5m)
|
||||||
|
2025-05-24 01:21:12,420 - INFO - [dataprovider_realtime.py:1382] - Loaded 1000 5m candles from Binance API
|
||||||
|
2025-05-24 01:21:12,445 - INFO - [dataprovider_realtime.py:1379] - Fetching 15m candles for ETH/USDT...
|
||||||
|
2025-05-24 01:21:12,457 - INFO - [dataprovider_realtime.py:337] - Loaded 1000 candles from cache: F:\projects\gogo2\cache\ETHUSDT_15m_candles.csv
|
||||||
|
2025-05-24 01:21:12,457 - INFO - [dataprovider_realtime.py:265] - Using cached historical data for ETH/USDT (15m)
|
||||||
|
2025-05-24 01:21:12,463 - INFO - [dataprovider_realtime.py:1382] - Loaded 1000 15m candles from Binance API
|
||||||
|
2025-05-24 01:21:12,487 - INFO - [dataprovider_realtime.py:1379] - Fetching 1h candles for ETH/USDT...
|
||||||
|
2025-05-24 01:21:12,492 - INFO - [dataprovider_realtime.py:337] - Loaded 1000 candles from cache: F:\projects\gogo2\cache\ETHUSDT_1h_candles.csv
|
||||||
|
2025-05-24 01:21:12,492 - INFO - [dataprovider_realtime.py:265] - Using cached historical data for ETH/USDT (1h)
|
||||||
|
2025-05-24 01:21:12,492 - INFO - [dataprovider_realtime.py:1382] - Loaded 1000 1h candles from Binance API
|
||||||
|
2025-05-24 01:21:12,519 - INFO - [dataprovider_realtime.py:1379] - Fetching 4h candles for ETH/USDT...
|
||||||
|
2025-05-24 01:21:12,524 - INFO - [dataprovider_realtime.py:337] - Loaded 1000 candles from cache: F:\projects\gogo2\cache\ETHUSDT_4h_candles.csv
|
||||||
|
2025-05-24 01:21:12,524 - INFO - [dataprovider_realtime.py:265] - Using cached historical data for ETH/USDT (4h)
|
||||||
|
2025-05-24 01:21:12,524 - INFO - [dataprovider_realtime.py:1382] - Loaded 1000 4h candles from Binance API
|
||||||
|
2025-05-24 01:21:12,550 - INFO - [dataprovider_realtime.py:1379] - Fetching 1d candles for ETH/USDT...
|
||||||
|
2025-05-24 01:21:12,552 - INFO - [dataprovider_realtime.py:337] - Loaded 1000 candles from cache: F:\projects\gogo2\cache\ETHUSDT_1d_candles.csv
|
||||||
|
2025-05-24 01:21:12,552 - INFO - [dataprovider_realtime.py:265] - Using cached historical data for ETH/USDT (1d)
|
||||||
|
2025-05-24 01:21:12,552 - INFO - [dataprovider_realtime.py:1382] - Loaded 1000 1d candles from Binance API
|
||||||
|
2025-05-24 01:21:12,584 - INFO - [dataprovider_realtime.py:1410] - Successfully loaded 6 timeframes from Binance API
|
||||||
|
2025-05-24 01:21:12,584 - INFO - [dataprovider_realtime.py:1414] - Loading 1s candles...
|
||||||
|
2025-05-24 01:21:12,584 - INFO - [dataprovider_realtime.py:333] - Using recent 1s cache (age: 7.6 minutes)
|
||||||
|
2025-05-24 01:21:12,587 - INFO - [dataprovider_realtime.py:337] - Loaded 300 candles from cache: F:\projects\gogo2\cache\ETHUSDT_1s_candles.csv
|
||||||
|
2025-05-24 01:21:12,587 - INFO - [dataprovider_realtime.py:265] - Using cached historical data for ETH/USDT (1s)
|
||||||
|
2025-05-24 01:21:12,587 - INFO - [dataprovider_realtime.py:1419] - Loaded 300 recent 1s candles from Binance API
|
||||||
|
2025-05-24 01:21:12,595 - INFO - [dataprovider_realtime.py:1505] - Final 1s candle count: 300
|
||||||
|
2025-05-24 01:21:12,595 - INFO - [dataprovider_realtime.py:1505] - Final 1m candle count: 1000
|
||||||
|
2025-05-24 01:21:12,595 - INFO - [dataprovider_realtime.py:1505] - Final 5m candle count: 1000
|
||||||
|
2025-05-24 01:21:12,595 - INFO - [dataprovider_realtime.py:1505] - Final 15m candle count: 1000
|
||||||
|
2025-05-24 01:21:12,595 - INFO - [dataprovider_realtime.py:1505] - Final 1h candle count: 1000
|
||||||
|
2025-05-24 01:21:12,595 - INFO - [dataprovider_realtime.py:1505] - Final 4h candle count: 1000
|
||||||
|
2025-05-24 01:21:12,595 - INFO - [dataprovider_realtime.py:1505] - Final 1d candle count: 1000
|
||||||
|
2025-05-24 01:21:12,598 - INFO - [dataprovider_realtime.py:1508] - Historical data loading completed. Has data: True
|
||||||
|
2025-05-24 01:21:12,598 - INFO - [dataprovider_realtime.py:1689] - Successfully loaded historical data for ETH/USDT
|
||||||
|
2025-05-24 01:21:12,598 - INFO - [dataprovider_realtime.py:1693] - 1s: 300 candles
|
||||||
|
2025-05-24 01:21:12,598 - INFO - [dataprovider_realtime.py:1693] - 1m: 1000 candles
|
||||||
|
2025-05-24 01:21:12,598 - INFO - [dataprovider_realtime.py:1693] - 5m: 1000 candles
|
||||||
|
2025-05-24 01:21:12,598 - INFO - [dataprovider_realtime.py:1693] - 15m: 1000 candles
|
||||||
|
2025-05-24 01:21:12,598 - INFO - [dataprovider_realtime.py:1693] - 1h: 1000 candles
|
||||||
|
2025-05-24 01:21:12,598 - INFO - [dataprovider_realtime.py:1713] - RealTimeChart initialized: ETH/USDT (1m)
|
||||||
|
2025-05-24 01:21:12,598 - INFO - [dataprovider_realtime.py:2142] - Retrieved 300 candles for 1s
|
||||||
|
2025-05-24 01:21:12,598 - INFO - [dataprovider_realtime.py:2142] - Retrieved 1000 candles for 1m
|
||||||
|
2025-05-24 01:21:12,600 - INFO - [test_chart_data.py:93] - 1s candles: 300
|
||||||
|
2025-05-24 01:21:12,600 - INFO - [test_chart_data.py:94] - 1m candles: 1000
|
||||||
|
2025-05-24 01:21:12,600 - INFO - [test_chart_data.py:98] - Latest 1m candle: 2025-05-23 22:21:00 - $2554.32
|
||||||
|
2025-05-24 01:21:12,602 - INFO - [test_chart_data.py:131] -
|
||||||
|
============================================================
|
||||||
|
2025-05-24 01:21:12,604 - INFO - [test_chart_data.py:133] - ============================================================
|
||||||
|
2025-05-24 01:21:12,608 - INFO - [test_chart_data.py:142] -
|
||||||
|
Passed: 3/3 tests
|
||||||
|
2025-05-24 01:21:54,373 - INFO - [dataprovider_realtime.py:978] - Detected local timezone: Europe/Kiev (Europe/Kiev)
|
||||||
|
2025-05-24 01:21:54,650 - INFO - [test_tick_cache.py:116] - ==================================================
|
||||||
|
2025-05-24 01:21:54,650 - INFO - [test_tick_cache.py:23] - Testing tick caching with timestamp serialization...
|
||||||
|
2025-05-24 01:21:54,650 - INFO - [dataprovider_realtime.py:1027] - Creating new tick storage for TEST/SYMBOL with timeframes ['1s', '1m']
|
||||||
|
2025-05-24 01:21:54,650 - INFO - [dataprovider_realtime.py:1028] - Cache directory: F:\projects\gogo2\cache\TESTSYMBOL
|
||||||
|
2025-05-24 01:21:54,651 - INFO - [dataprovider_realtime.py:1029] - Cache file: F:\projects\gogo2\cache\TESTSYMBOL\TESTSYMBOL_ticks.json
|
||||||
|
2025-05-24 01:21:54,651 - INFO - [dataprovider_realtime.py:1034] - TickStorage: TimescaleDB integration is DISABLED for TEST/SYMBOL
|
||||||
|
2025-05-24 01:21:54,651 - INFO - [test_tick_cache.py:55] - Adding tick 1: price=$100.0, timestamp type=<class 'pandas._libs.tslibs.timestamps.Timestamp'>
|
||||||
|
2025-05-24 01:21:54,652 - INFO - [test_tick_cache.py:55] - Adding tick 2: price=$101.0, timestamp type=<class 'datetime.datetime'>
|
||||||
|
2025-05-24 01:21:54,652 - INFO - [test_tick_cache.py:55] - Adding tick 3: price=$102.0, timestamp type=<class 'int'>
|
||||||
|
2025-05-24 01:21:54,652 - INFO - [test_tick_cache.py:58] - Total ticks in storage: 3
|
||||||
|
2025-05-24 01:21:54,653 - INFO - [test_tick_cache.py:62] - Saved ticks to cache
|
||||||
|
2025-05-24 01:21:54,662 - INFO - [test_tick_cache.py:72] - Cache contains 3 ticks
|
||||||
|
2025-05-24 01:21:54,662 - INFO - [test_tick_cache.py:77] - First tick in cache: {'price': 100.0, 'quantity': 1.0, 'timestamp': '2025-05-24T01:21:54.651200'}
|
||||||
|
2025-05-24 01:21:54,662 - INFO - [test_tick_cache.py:78] - Timestamp type in cache: <class 'str'>
|
||||||
|
2025-05-24 01:21:54,662 - INFO - [test_tick_cache.py:84] - Creating new TickStorage instance to test loading...
|
||||||
|
2025-05-24 01:21:54,662 - INFO - [dataprovider_realtime.py:1027] - Creating new tick storage for TEST/SYMBOL with timeframes ['1s', '1m']
|
||||||
|
2025-05-24 01:21:54,662 - INFO - [dataprovider_realtime.py:1028] - Cache directory: F:\projects\gogo2\cache\TESTSYMBOL
|
||||||
|
2025-05-24 01:21:54,663 - INFO - [dataprovider_realtime.py:1029] - Cache file: F:\projects\gogo2\cache\TESTSYMBOL\TESTSYMBOL_ticks.json
|
||||||
|
2025-05-24 01:21:54,663 - INFO - [dataprovider_realtime.py:1034] - TickStorage: TimescaleDB integration is DISABLED for TEST/SYMBOL
|
||||||
|
2025-05-24 01:21:54,663 - INFO - [dataprovider_realtime.py:1091] - Loaded 3 ticks from cache
|
||||||
|
2025-05-24 01:21:54,666 - INFO - [test_tick_cache.py:95] - Loaded tick 1: price=$100.0, timestamp=2025-05-24 01:21:54.651200, type=<class 'pandas._libs.tslibs.timestamps.Timestamp'>
|
||||||
|
2025-05-24 01:21:54,666 - INFO - [test_tick_cache.py:95] - Loaded tick 2: price=$101.0, timestamp=2025-05-24 01:21:54.651200, type=<class 'pandas._libs.tslibs.timestamps.Timestamp'>
|
||||||
|
2025-05-24 01:21:54,666 - INFO - [test_tick_cache.py:95] - Loaded tick 3: price=$102.0, timestamp=2025-05-23 22:21:54.651000, type=<class 'pandas._libs.tslibs.timestamps.Timestamp'>
|
||||||
|
2025-05-24 01:21:54,667 - INFO - [test_tick_cache.py:120] -
|
||||||
|
==================================================
|
||||||
|
130
test_tick_cache.py
Normal file
130
test_tick_cache.py
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Test script to verify tick caching with timestamp serialization
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import pandas as pd
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# Add the project root to the path
|
||||||
|
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
from dataprovider_realtime import TickStorage
|
||||||
|
|
||||||
|
# Set up logging
|
||||||
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
def test_tick_caching():
|
||||||
|
"""Test tick caching with pandas Timestamps"""
|
||||||
|
logger.info("Testing tick caching with timestamp serialization...")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Create tick storage
|
||||||
|
tick_storage = TickStorage("TEST/SYMBOL", ["1s", "1m"])
|
||||||
|
|
||||||
|
# Clear any existing cache
|
||||||
|
if os.path.exists(tick_storage.cache_path):
|
||||||
|
os.remove(tick_storage.cache_path)
|
||||||
|
logger.info("Cleared existing cache file")
|
||||||
|
|
||||||
|
# Add some test ticks with different timestamp formats
|
||||||
|
test_ticks = [
|
||||||
|
{
|
||||||
|
'price': 100.0,
|
||||||
|
'quantity': 1.0,
|
||||||
|
'timestamp': pd.Timestamp.now()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'price': 101.0,
|
||||||
|
'quantity': 1.5,
|
||||||
|
'timestamp': datetime.now()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'price': 102.0,
|
||||||
|
'quantity': 2.0,
|
||||||
|
'timestamp': int(datetime.now().timestamp() * 1000) # milliseconds
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add ticks
|
||||||
|
for i, tick in enumerate(test_ticks):
|
||||||
|
logger.info(f"Adding tick {i+1}: price=${tick['price']}, timestamp type={type(tick['timestamp'])}")
|
||||||
|
tick_storage.add_tick(tick)
|
||||||
|
|
||||||
|
logger.info(f"Total ticks in storage: {len(tick_storage.ticks)}")
|
||||||
|
|
||||||
|
# Force save to cache
|
||||||
|
tick_storage._save_to_cache()
|
||||||
|
logger.info("Saved ticks to cache")
|
||||||
|
|
||||||
|
# Verify cache file exists
|
||||||
|
if os.path.exists(tick_storage.cache_path):
|
||||||
|
logger.info(f"✅ Cache file created: {tick_storage.cache_path}")
|
||||||
|
|
||||||
|
# Check file content
|
||||||
|
with open(tick_storage.cache_path, 'r') as f:
|
||||||
|
import json
|
||||||
|
cache_content = json.load(f)
|
||||||
|
logger.info(f"Cache contains {len(cache_content)} ticks")
|
||||||
|
|
||||||
|
# Show first tick to verify format
|
||||||
|
if cache_content:
|
||||||
|
first_tick = cache_content[0]
|
||||||
|
logger.info(f"First tick in cache: {first_tick}")
|
||||||
|
logger.info(f"Timestamp type in cache: {type(first_tick['timestamp'])}")
|
||||||
|
else:
|
||||||
|
logger.error("❌ Cache file was not created")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Create new tick storage instance to test loading
|
||||||
|
logger.info("Creating new TickStorage instance to test loading...")
|
||||||
|
new_tick_storage = TickStorage("TEST/SYMBOL", ["1s", "1m"])
|
||||||
|
|
||||||
|
# Load from cache
|
||||||
|
cache_loaded = new_tick_storage._load_from_cache()
|
||||||
|
|
||||||
|
if cache_loaded:
|
||||||
|
logger.info(f"✅ Successfully loaded {len(new_tick_storage.ticks)} ticks from cache")
|
||||||
|
|
||||||
|
# Verify timestamps are properly converted back to pandas Timestamps
|
||||||
|
for i, tick in enumerate(new_tick_storage.ticks):
|
||||||
|
logger.info(f"Loaded tick {i+1}: price=${tick['price']}, timestamp={tick['timestamp']}, type={type(tick['timestamp'])}")
|
||||||
|
|
||||||
|
if not isinstance(tick['timestamp'], pd.Timestamp):
|
||||||
|
logger.error(f"❌ Timestamp not properly converted back to pandas.Timestamp: {type(tick['timestamp'])}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
logger.info("✅ All timestamps properly converted back to pandas.Timestamp")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.error("❌ Failed to load ticks from cache")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"❌ Error in tick caching test: {str(e)}")
|
||||||
|
import traceback
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
|
return False
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Run the test"""
|
||||||
|
logger.info("🧪 Starting tick caching test...")
|
||||||
|
logger.info("=" * 50)
|
||||||
|
|
||||||
|
success = test_tick_caching()
|
||||||
|
|
||||||
|
logger.info("\n" + "=" * 50)
|
||||||
|
if success:
|
||||||
|
logger.info("🎉 Tick caching test PASSED!")
|
||||||
|
else:
|
||||||
|
logger.error("❌ Tick caching test FAILED!")
|
||||||
|
|
||||||
|
return success
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
success = main()
|
||||||
|
sys.exit(0 if success else 1)
|
Reference in New Issue
Block a user