2025-06-07 01:17:22 +08:00
|
|
|
"""
|
|
|
|
|
Utility functions for market data aggregation.
|
|
|
|
|
|
|
|
|
|
This module provides common utility functions for working with OHLCV candles
|
|
|
|
|
and trade data aggregation.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import re
|
|
|
|
|
from typing import List, Tuple
|
2025-06-11 18:36:34 +08:00
|
|
|
from utils.timeframe_utils import load_timeframe_options
|
2025-06-07 01:17:22 +08:00
|
|
|
|
|
|
|
|
from ..data_types import StandardizedTrade, OHLCVCandle
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def aggregate_trades_to_candles(trades: List[StandardizedTrade],
|
|
|
|
|
timeframes: List[str],
|
|
|
|
|
symbol: str,
|
|
|
|
|
exchange: str) -> List[OHLCVCandle]:
|
|
|
|
|
"""
|
|
|
|
|
Simple utility function to aggregate a list of trades to candles.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
trades: List of standardized trades
|
|
|
|
|
timeframes: List of timeframes to generate
|
|
|
|
|
symbol: Trading symbol
|
|
|
|
|
exchange: Exchange name
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
List of completed candles
|
|
|
|
|
"""
|
2025-06-09 14:18:32 +08:00
|
|
|
from .batch import BatchCandleProcessor
|
2025-06-07 01:17:22 +08:00
|
|
|
processor = BatchCandleProcessor(symbol, exchange, timeframes)
|
|
|
|
|
return processor.process_trades_to_candles(iter(trades))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def validate_timeframe(timeframe: str) -> bool:
|
|
|
|
|
"""
|
|
|
|
|
Validate if timeframe is supported.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
timeframe: Timeframe string (e.g., '1s', '5s', '10s', '1m', '5m', '1h')
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
True if supported, False otherwise
|
|
|
|
|
"""
|
2025-06-11 18:36:34 +08:00
|
|
|
supported = [item['value'] for item in load_timeframe_options()]
|
2025-06-07 01:17:22 +08:00
|
|
|
return timeframe in supported
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_timeframe(timeframe: str) -> Tuple[int, str]:
|
|
|
|
|
"""
|
|
|
|
|
Parse timeframe string into number and unit.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
timeframe: Timeframe string (e.g., '1s', '5m', '1h')
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
Tuple of (number, unit)
|
|
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
'1s' -> (1, 's')
|
|
|
|
|
'5m' -> (5, 'm')
|
|
|
|
|
'1h' -> (1, 'h')
|
|
|
|
|
'1d' -> (1, 'd')
|
|
|
|
|
"""
|
|
|
|
|
match = re.match(r'^(\d+)([smhd])$', timeframe.lower())
|
|
|
|
|
if not match:
|
|
|
|
|
raise ValueError(f"Invalid timeframe format: {timeframe}")
|
|
|
|
|
number = int(match.group(1))
|
|
|
|
|
unit = match.group(2)
|
2025-06-09 14:18:32 +08:00
|
|
|
# Disallow zero or negative timeframes, as they are not meaningful for bucket intervals
|
|
|
|
|
if number <= 0:
|
|
|
|
|
raise ValueError(f"Timeframe value must be positive: {timeframe}")
|
2025-06-07 01:17:22 +08:00
|
|
|
return number, unit
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__all__ = [
|
|
|
|
|
'aggregate_trades_to_candles',
|
|
|
|
|
'validate_timeframe',
|
|
|
|
|
'parse_timeframe'
|
|
|
|
|
]
|