""" 行业数据查询和计算工具 """ import logging from typing import Optional, Dict, Any from app.models.industry import Industry logger = logging.getLogger(__name__) async def get_industry_data_by_name(industry_name: str) -> Optional[Dict[str, Any]]: """ 根据行业名称查询行业数据 Args: industry_name: 行业名称 Returns: 包含行业数据的字典,如果未找到则返回None { 'code': '行业代码', 'name': '行业名称', 'roe': 平均ROE, 'fix_num': 行业修正系数, 'remark': '备注' } """ try: industry = await Industry.filter(name=industry_name).first() if industry: return { 'code': industry.code, 'name': industry.name, 'roe': industry.roe, 'fix_num': industry.fix_num, 'remark': industry.remark } else: logger.warning(f"未找到行业数据: {industry_name}") return None except Exception as e: logger.error(f"查询行业数据失败: {industry_name}, 错误: {str(e)}") return None async def calculate_industry_average_s2(industry_name: str) -> float: """ 计算行业均值S2 Args: industry_name: 行业名称 Returns: 行业均值S2,如果查询失败则返回0.0 """ try: industry_data = await get_industry_data_by_name(industry_name) if industry_data: # S2 = ROE * 修正系数 roe = industry_data.get('roe', 0.0) fix_num = industry_data.get('fix_num', 0.0) s2_value = roe * fix_num # 确保S2值为正数,避免对数计算错误 if s2_value <= 0: logger.warning(f"行业 {industry_name} S2计算值为负数或零: ROE={roe}, 修正系数={fix_num}, S2={s2_value},使用默认值0.01") s2_value = 0.01 # 使用小的正数避免对数计算错误 logger.info(f"行业 {industry_name} S2计算: ROE={roe}, 修正系数={fix_num}, S2={s2_value}") return s2_value else: logger.warning(f"未找到行业 {industry_name} 的数据,返回默认值0.01") return 0.01 # 返回小的正数而不是0.0 except Exception as e: logger.error(f"计算行业均值S2失败: {industry_name}, 错误: {str(e)}") return 0.01 # 返回小的正数而不是0.0 async def get_all_industries() -> list: """ 获取所有行业列表 Returns: 行业列表 """ try: industries = await Industry.all() return [ { 'code': industry.code, 'name': industry.name, 'roe': industry.roe, 'fix_num': industry.fix_num, 'remark': industry.remark } for industry in industries ] except Exception as e: logger.error(f"获取行业列表失败: {str(e)}") return []