guzhi/app/utils/industry_calculator.py
邹方成 2322dbad00 feat: 添加估值计算功能并优化相关逻辑
refactor(valuation): 重构估值计算参数提取逻辑
fix: 修复行业均值S2计算中的除零错误
feat(api): 新增微信指数计算工具和行业数据查询工具
feat(schema): 在估值模型中添加计算结果字段
refactor: 优化动态质押率计算中的月交易额解析
fix: 处理日期解析异常时返回默认值
docs: 更新API文档中的估值计算请求示例
2025-10-10 16:33:59 +08:00

100 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
行业数据查询和计算工具
"""
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 []