54 lines
1.6 KiB
Python
54 lines
1.6 KiB
Python
import logging
|
|
from datetime import datetime
|
|
|
|
def setup_logger(name: str, log_file: str = None, level: str = 'INFO') -> logging.Logger:
|
|
logger = logging.getLogger(name)
|
|
logger.setLevel(getattr(logging, level.upper()))
|
|
|
|
if not logger.handlers:
|
|
formatter = logging.Formatter(
|
|
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
)
|
|
|
|
console_handler = logging.StreamHandler()
|
|
console_handler.setFormatter(formatter)
|
|
logger.addHandler(console_handler)
|
|
|
|
if log_file:
|
|
file_handler = logging.FileHandler(log_file)
|
|
file_handler.setFormatter(formatter)
|
|
logger.addHandler(file_handler)
|
|
|
|
return logger
|
|
|
|
def safe_divide(a: float, b: float, default: float = 0) -> float:
|
|
try:
|
|
return a / b if b != 0 else default
|
|
except (TypeError, ZeroDivisionError):
|
|
return default
|
|
|
|
def format_number(num: float, decimals: int = 2) -> str:
|
|
try:
|
|
if num == float('inf'):
|
|
return '∞'
|
|
elif num == float('-inf'):
|
|
return '-∞'
|
|
else:
|
|
return f"{num:.{decimals}f}"
|
|
except:
|
|
return "N/A"
|
|
|
|
def get_current_date() -> str:
|
|
return datetime.now().strftime('%Y%m%d')
|
|
|
|
def validate_ts_code(ts_code: str) -> bool:
|
|
if not ts_code or not isinstance(ts_code, str):
|
|
return False
|
|
|
|
parts = ts_code.split('.')
|
|
if len(parts) != 2:
|
|
return False
|
|
|
|
stock_code, exchange = parts
|
|
return (len(stock_code) == 6 and stock_code.isdigit() and
|
|
exchange in ['SH', 'SZ']) |