Remove deprecated modules and files related to the backtesting framework, including backtest.py, cli.py, config.py, data.py, intrabar.py, logging_utils.py, market_costs.py, metrics.py, trade.py, and supertrend indicators. Introduce a new structure for the backtesting engine with improved organization and functionality, including a CLI handler, data manager, and reporting capabilities. Update dependencies in pyproject.toml to support the new architecture.

This commit is contained in:
2026-01-12 21:11:39 +08:00
parent c4aa965a98
commit 44fac1ed25
37 changed files with 5253 additions and 393 deletions

124
engine/logging_config.py Normal file
View File

@@ -0,0 +1,124 @@
"""
Centralized logging configuration for the backtest engine.
Provides colored console output and rotating file logs.
"""
import logging
import sys
from logging.handlers import RotatingFileHandler
from pathlib import Path
# ANSI color codes for terminal output
class Colors:
"""ANSI escape codes for colored terminal output."""
RESET = "\033[0m"
BOLD = "\033[1m"
# Log level colors
DEBUG = "\033[36m" # Cyan
INFO = "\033[32m" # Green
WARNING = "\033[33m" # Yellow
ERROR = "\033[31m" # Red
CRITICAL = "\033[35m" # Magenta
class ColoredFormatter(logging.Formatter):
"""
Custom formatter that adds colors to log level names in terminal output.
"""
LEVEL_COLORS = {
logging.DEBUG: Colors.DEBUG,
logging.INFO: Colors.INFO,
logging.WARNING: Colors.WARNING,
logging.ERROR: Colors.ERROR,
logging.CRITICAL: Colors.CRITICAL,
}
def __init__(self, fmt: str = None, datefmt: str = None):
super().__init__(fmt, datefmt)
def format(self, record: logging.LogRecord) -> str:
# Save original levelname
original_levelname = record.levelname
# Add color to levelname
color = self.LEVEL_COLORS.get(record.levelno, Colors.RESET)
record.levelname = f"{color}{record.levelname}{Colors.RESET}"
# Format the message
result = super().format(record)
# Restore original levelname
record.levelname = original_levelname
return result
def setup_logging(
log_dir: str = "logs",
log_level: int = logging.INFO,
console_level: int = logging.INFO,
max_bytes: int = 5 * 1024 * 1024, # 5MB
backup_count: int = 3
) -> None:
"""
Configure logging for the application.
Args:
log_dir: Directory for log files
log_level: File logging level
console_level: Console logging level
max_bytes: Max size per log file before rotation
backup_count: Number of backup files to keep
"""
log_path = Path(log_dir)
log_path.mkdir(parents=True, exist_ok=True)
# Get root logger
root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG) # Capture all, handlers filter
# Clear existing handlers
root_logger.handlers.clear()
# Console handler with colors
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(console_level)
console_fmt = ColoredFormatter(
fmt="[%(asctime)s] %(levelname)s - %(message)s",
datefmt="%H:%M:%S"
)
console_handler.setFormatter(console_fmt)
root_logger.addHandler(console_handler)
# File handler with rotation
file_handler = RotatingFileHandler(
log_path / "backtest.log",
maxBytes=max_bytes,
backupCount=backup_count,
encoding="utf-8"
)
file_handler.setLevel(log_level)
file_fmt = logging.Formatter(
fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
file_handler.setFormatter(file_fmt)
root_logger.addHandler(file_handler)
def get_logger(name: str) -> logging.Logger:
"""
Get a logger instance for the given module name.
Args:
name: Module name (typically __name__)
Returns:
Configured logger instance
"""
return logging.getLogger(name)