# -*- coding: utf-8 -*- """ 动态保险定价模型 基于精算原理,结合六维风险评分实现"千企千面"费率计算 """ import logging import sys import os # 将项目根目录添加到 Python 路径 sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from config import INSURANCE_PRODUCTS logger = logging.getLogger(__name__) # 行业风险系数 INDUSTRY_RISK_FACTORS = { "芯片": 1.35, # 地缘风险+技术迭代双高 "AI": 1.30, # 合规风险+技术竞争 "软件": 1.05, # 相对成熟 "医疗器械": 0.95, # 技术壁垒高但风险较稳 "新能源": 1.15, # 技术路线之争+贸易摩擦 "消费电子": 1.10, # 供应链风险 } # 企业规模折扣(大企业风险分散能力更强) SCALE_DISCOUNT = { "超大型": 0.85, # 营收 > 500亿 "大型": 0.90, # 100-500亿 "中型": 1.00, # 10-100亿 "小型": 1.15, # 1-10亿 "微型": 1.30, # < 1亿 } def get_enterprise_scale(revenue: float) -> str: """根据营收判断企业规模""" if revenue >= 50_000_000_000: return "超大型" elif revenue >= 10_000_000_000: return "大型" elif revenue >= 1_000_000_000: return "中型" elif revenue >= 100_000_000: return "小型" return "微型" def calculate_premium( product_key: str, comprehensive_risk_score: int, six_dimension_scores: dict, sector: str = "", revenue: float = 0, ) -> dict: """ 动态费率计算器 定价公式: 实际保费 = 基础保费 × 风险系数 × 行业调整 × 规模折扣 风险系数由综合评分决定(分段线性): - [0, 30) → 0.7 ~ 0.9(优质折扣) - [30, 50) → 0.9 ~ 1.2(标准浮动) - [50, 70) → 1.2 ~ 1.8(风险上浮) - [70, 90) → 1.8 ~ 2.5(惩罚性费率) - [90,100] → 拒保或附加极高免赔额 """ product = INSURANCE_PRODUCTS.get(product_key) if not product: return {"error": f"未知保险产品: {product_key}"} base_premium = product["base_premium"] base_coverage = product["base_coverage"] # 1. 计算风险系数 risk_multiplier = _calculate_risk_multiplier(comprehensive_risk_score) # 2. 行业调整系数 industry_factor = INDUSTRY_RISK_FACTORS.get(sector, 1.0) # 3. 规模折扣 scale = get_enterprise_scale(revenue) scale_factor = SCALE_DISCOUNT[scale] # 4. 特定险种的维度调整 dimension_adjustment = _get_dimension_adjustment(product_key, six_dimension_scores) # 5. 最终保费 final_premium = base_premium * risk_multiplier * industry_factor * scale_factor * dimension_adjustment # 6. 核保条件 deductible_rate = _calculate_deductible(comprehensive_risk_score) adjusted_coverage = base_coverage * (1.0 if comprehensive_risk_score < 70 else 0.7) return { "product_name": product["name"], "product_key": product_key, "base_premium": base_premium, "base_coverage": base_coverage, "risk_multiplier": round(risk_multiplier, 3), "industry_factor": round(industry_factor, 3), "scale_factor": round(scale_factor, 3), "scale_label": scale, "dimension_adjustment": round(dimension_adjustment, 3), "final_premium": round(final_premium, 2), "adjusted_coverage": round(adjusted_coverage, 2), "deductible_rate": round(deductible_rate, 3), "deductible_amount": round(adjusted_coverage * deductible_rate, 2), "comprehensive_risk_score": comprehensive_risk_score, "is_insurable": comprehensive_risk_score < 90, "pricing_breakdown": ( f"¥{base_premium:,.0f} × {risk_multiplier:.2f}(风险) " f"× {industry_factor:.2f}(行业) × {scale_factor:.2f}(规模) " f"× {dimension_adjustment:.2f}(维度) = ¥{final_premium:,.0f}" ), } def _calculate_risk_multiplier(score: int) -> float: """分段线性风险系数计算""" if score < 30: return 0.7 + (score / 30) * 0.2 # 0.7 ~ 0.9 elif score < 50: return 0.9 + ((score - 30) / 20) * 0.3 # 0.9 ~ 1.2 elif score < 70: return 1.2 + ((score - 50) / 20) * 0.6 # 1.2 ~ 1.8 elif score < 90: return 1.8 + ((score - 70) / 20) * 0.7 # 1.8 ~ 2.5 else: return 3.0 # 拒保级别 def _get_dimension_adjustment(product_key: str, scores: dict) -> float: """针对特定险种,根据相关维度得分进行微调""" if product_key == "ip_lawsuit": # 知识产权被诉险:重点看技术路线和专利 tech_score = scores.get("tech_disruption", 50) return 0.8 + (tech_score / 100) * 0.4 # 0.8 ~ 1.2 elif product_key == "exec_departure": # 高管离职险:重点看人员流失风险 talent_score = scores.get("talent_loss", 50) return 0.7 + (talent_score / 100) * 0.6 # 0.7 ~ 1.3 elif product_key == "data_compliance": # 数据合规险:重点看合规风险 compliance_score = scores.get("algo_compliance", 50) return 0.8 + (compliance_score / 100) * 0.4 # 0.8 ~ 1.2 return 1.0 def _calculate_deductible(score: int) -> float: """计算免赔率""" if score < 30: return 0.05 # 5% elif score < 50: return 0.10 # 10% elif score < 70: return 0.15 # 15% elif score < 90: return 0.25 # 25% else: return 0.50 # 50%(惩罚性高免赔) def calculate_all_products( comprehensive_risk_score: int, six_dimension_scores: dict, sector: str = "", revenue: float = 0, ) -> list: """计算所有险种的保费""" results = [] for product_key in INSURANCE_PRODUCTS: result = calculate_premium( product_key, comprehensive_risk_score, six_dimension_scores, sector, revenue, ) results.append(result) return results