feat: 添加市场数据检查脚本和日志配置模块

添加 check_market_data.py 脚本用于检查行情数据完整性
实现 Tushare API 管理、交易日历缓存和在线数据检查功能
添加 log_style.py 模块提供灵活的日志配置功能
创建相关批处理文件和日志文件
This commit is contained in:
2025-12-05 23:04:32 +08:00
commit d02856fa5c
12 changed files with 4181 additions and 0 deletions

197
log_style.py Normal file
View File

@@ -0,0 +1,197 @@
# -*- coding: utf-8 -*-
"""
日志配置模块
提供灵活的日志系统配置功能
"""
import logging
import os
import sys
from logging.handlers import TimedRotatingFileHandler
from datetime import datetime
# 默认日志配置
DEFAULT_LOG_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
DEFAULT_DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
DEFAULT_LOG_LEVEL = logging.INFO
# 全局日志记录器缓存
_loggers = {}
def setup_logger(
name='backtrader',
log_file=None,
level=DEFAULT_LOG_LEVEL,
log_format=DEFAULT_LOG_FORMAT,
date_format=DEFAULT_DATE_FORMAT,
console=True,
file_level=None,
log_dir='logs',
backup_count=7
):
"""
配置日志记录器
Args:
name: 日志记录器名称
log_file: 日志文件路径如果为None则自动生成
level: 日志级别
log_format: 日志格式
date_format: 日期格式
console: 是否输出到控制台
file_level: 文件日志级别如果为None则使用level
log_dir: 日志文件目录
backup_count: 日志文件保留数量
Returns:
logging.Logger: 配置好的日志记录器
"""
# 如果日志记录器已存在,则直接返回
if name in _loggers:
return _loggers[name]
# 创建日志记录器
logger = logging.getLogger(name)
logger.setLevel(level)
# 避免重复添加处理器
if logger.handlers:
logger.handlers.clear()
# 创建格式化器
formatter = logging.Formatter(log_format, datefmt=date_format)
# 添加控制台处理器
if console:
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(level)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
# 添加文件处理器
if log_file or log_dir:
# 确保日志目录存在
if log_dir and not os.path.exists(log_dir):
try:
os.makedirs(log_dir)
except Exception as e:
logger.error(f'创建日志目录失败: {str(e)}')
# 生成日志文件名
if not log_file:
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
log_file = os.path.join(log_dir, f'{name}_{timestamp}.log')
# 使用TimedRotatingFileHandler实现按时间轮换
try:
file_handler = TimedRotatingFileHandler(
log_file,
when='midnight',
interval=1,
backupCount=backup_count,
encoding='utf-8'
)
# 设置文件日志级别
file_handler.setLevel(file_level or level)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.info(f'日志文件已配置: {log_file}')
except Exception as e:
logger.error(f'配置日志文件失败: {str(e)}')
# 保存到缓存
_loggers[name] = logger
return logger
def get_logger(name='backtrader'):
"""
获取日志记录器
Args:
name: 日志记录器名称
Returns:
logging.Logger: 日志记录器
"""
if name not in _loggers:
# 如果日志记录器不存在,则创建默认配置的日志记录器
return setup_logger(name)
return _loggers[name]
def set_global_level(level):
"""
设置所有已创建日志记录器的全局级别
Args:
level: 日志级别
"""
for logger_name, logger in _loggers.items():
logger.setLevel(level)
# 设置所有处理器的级别
for handler in logger.handlers:
handler.setLevel(level)
def shutdown_loggers():
"""
关闭所有日志记录器
"""
logging.shutdown()
_loggers.clear()
def log_exception(logger_name='backtrader', message='发生异常', exc_info=True):
"""
记录异常信息
Args:
logger_name: 日志记录器名称
message: 异常消息
exc_info: 是否记录异常堆栈信息
"""
logger = get_logger(logger_name)
logger.error(message, exc_info=exc_info)
def create_specialized_logger(
name,
log_file=None,
level=DEFAULT_LOG_LEVEL,
console=True,
**kwargs
):
"""
创建专门用途的日志记录器
Args:
name: 日志记录器名称
log_file: 日志文件路径
level: 日志级别
console: 是否输出到控制台
**kwargs: 其他参数
Returns:
logging.Logger: 配置好的日志记录器
"""
# 构建专用日志格式
specialized_format = kwargs.get(
'log_format',
f'[%(asctime)s] [{name.upper()}] [%(levelname)s] %(message)s'
)
return setup_logger(
name=name,
log_file=log_file,
level=level,
log_format=specialized_format,
console=console,
**kwargs
)