from .insurance_loss_ratio_types import LossRatios from .math_round_div import RoundingMode, round_div from .money_amount import Money, assert_same_currency def loss_ratios(earned_premium: Money, incurred_claims: Money, expenses: Money, mode: RoundingMode) -> LossRatios: """Loss, expense and combined ratios against earned premium, in basis points. The combined ratio is worked from claims plus expenses, rounded once, not by adding the two rounded ratios, so it can differ from their sum by one basis point: 1.00 and 1.00 on 3.00 are 33.33% each but 66.67% together. """ assert_same_currency(earned_premium, incurred_claims) assert_same_currency(earned_premium, expenses) if earned_premium.minor <= 0: raise ValueError("earnedPremium must be more than zero, received %d" % (earned_premium.minor,)) p = earned_premium.minor return LossRatios( loss_ratio_basis_points=round_div(incurred_claims.minor * 10000, p, mode), expense_ratio_basis_points=round_div(expenses.minor * 10000, p, mode), combined_ratio_basis_points=round_div((incurred_claims.minor + expenses.minor) * 10000, p, mode), )