|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
| 3 | +import numpy as np |
| 4 | + |
3 | 5 | from faslr.base_table import FTableView |
4 | 6 |
|
5 | 7 | from faslr.model import ( |
|
9 | 11 | FModelWidget |
10 | 12 | ) |
11 | 13 |
|
| 14 | +from faslr.style.triangle import ( |
| 15 | + PERCENT_STYLE, |
| 16 | + RATIO_STYLE, |
| 17 | + VALUE_STYLE |
| 18 | +) |
| 19 | + |
12 | 20 | from faslr.methods.expected_loss import ( |
13 | 21 | ExpectedLossAprioriWidget, |
14 | 22 | ExpectedLossRatioWidget |
15 | 23 | ) |
16 | 24 |
|
| 25 | +from faslr.utilities import ( |
| 26 | + fetch_cdf, |
| 27 | + fetch_latest_diagonal, |
| 28 | + fetch_origin, |
| 29 | + fetch_ultimate |
| 30 | +) |
| 31 | + |
17 | 32 | from PyQt6.QtCore import ( |
18 | 33 | Qt |
19 | 34 | ) |
|
24 | 39 | QTabWidget |
25 | 40 | ) |
26 | 41 |
|
27 | | -from typing import TYPE_CHECKING |
| 42 | +from typing import TYPE_CHECKING, Any |
28 | 43 |
|
29 | 44 | if TYPE_CHECKING: |
30 | 45 | from chainladder import Chainladder |
@@ -103,14 +118,60 @@ def __init__( |
103 | 118 | ): |
104 | 119 | super().__init__(parent=parent) |
105 | 120 | self._data['On-Level Earned Premium'] = self.parent.parent.apriori_tab.model._data['On-Level Earned Premium'] |
106 | | - self._data['Paid Losses'] = self.parent.parent.apriori_tab.model._data['Paid Losses'] |
107 | | - self._data['Reported Losses'] = self.parent.parent.apriori_tab.model._data['Reported Losses'] |
108 | 121 | self._data = self._data.rename(columns={'Selected Averages': 'Selected Loss Ratio'}) |
| 122 | + self._data['Expected Claims'] = self._data['Selected Loss Ratio'] * self._data['On-Level Earned Premium'] |
| 123 | + self._data['Reported CDF'] = np.maximum(1, self.parent.parent.apriori_tab.model._data['Reported CDF']) |
| 124 | + self._data['Paid CDF'] = np.maximum(1, self.parent.parent.apriori_tab.model._data['Paid CDF']) |
| 125 | + self._data['% Unreported'] = 1 - self._data['Reported CDF'] ** (-1) |
| 126 | + self._data['% Unpaid'] = 1 - self._data['Paid CDF'] ** (-1) |
| 127 | + self._data['Expected Unreported'] = self._data['% Unreported'] * self._data['Expected Claims'] |
| 128 | + self._data['Expected Unpaid'] = self._data['% Unpaid'] * self._data['Expected Claims'] |
| 129 | + self._data['Reported Losses'] = self.parent.parent.apriori_tab.model._data['Reported Losses'] |
| 130 | + self._data['Paid Losses'] = self.parent.parent.apriori_tab.model._data['Paid Losses'] |
| 131 | + self._data['Ultimate BF Reported'] = self._data['Expected Unreported'] + self._data['Reported Losses'] |
| 132 | + self._data['Ultimate BF Paid'] = self._data['Expected Unpaid'] + self._data['Paid Losses'] |
| 133 | + self._data['Case Outstanding'] = self._data['Reported Losses'] - self._data['Paid Losses'] |
| 134 | + self._data['BF Reported IBNR'] = self._data['Ultimate BF Reported'] - self._data['Reported Losses'] |
| 135 | + self._data['BF Paid IBNR'] = self._data['Ultimate BF Paid'] - self._data['Reported Losses'] |
| 136 | + self._data['BF Reported Unpaid Claims'] = self._data['Ultimate BF Reported'] - self._data['Paid Losses'] |
| 137 | + self._data['BF Paid Unpaid Claims'] = self._data['Ultimate BF Paid'] - self._data['Paid Losses'] |
| 138 | + |
| 139 | + |
| 140 | + def data(self, index, role = ...) -> Any: |
| 141 | + if role == Qt.ItemDataRole.DisplayRole: |
| 142 | + |
| 143 | + value = self._data.iloc[index.row(), index.column()] |
| 144 | + col = self._data.columns[index.column()] |
| 145 | + |
| 146 | + if np.isnan(value): |
| 147 | + return "" |
| 148 | + elif col in [ |
| 149 | + 'Selected Loss Ratio', |
| 150 | + '% Unreported', |
| 151 | + '% Unpaid' |
| 152 | + ]: |
| 153 | + return PERCENT_STYLE.format(value) |
| 154 | + elif col in [ |
| 155 | + 'Reported CDF', |
| 156 | + 'Paid CDF' |
| 157 | + ]: |
| 158 | + return RATIO_STYLE.format(value) |
| 159 | + else: |
| 160 | + return VALUE_STYLE.format(value) |
109 | 161 |
|
110 | 162 | def setData(self, index, value, role = ...) -> bool: |
111 | 163 |
|
112 | 164 | if role == Qt.ItemDataRole.EditRole: |
113 | 165 | self._data['Selected Loss Ratio'] = self.parent_model.selected_ratios_row.T['Selected Averages'] |
| 166 | + self._data['Expected Claims'] = self._data['Selected Loss Ratio'] * self._data['On-Level Earned Premium'] |
| 167 | + self._data['Expected Unreported'] = self._data['% Unreported'] * self._data['Expected Claims'] |
| 168 | + self._data['Expected Unpaid'] = self._data['% Unpaid'] * self._data['Expected Claims'] |
| 169 | + self._data['Ultimate BF Reported'] = self._data['Expected Unreported'] + self._data['Reported Losses'] |
| 170 | + self._data['Ultimate BF Paid'] = self._data['Expected Unpaid'] + self._data['Paid Losses'] |
| 171 | + self._data['BF Reported IBNR'] = self._data['Ultimate BF Reported'] - self._data['Reported Losses'] |
| 172 | + self._data['BF Paid IBNR'] = self._data['Ultimate BF Paid'] - self._data['Reported Losses'] |
| 173 | + self._data['BF Reported Unpaid Claims'] = self._data['Ultimate BF Reported'] - self._data['Paid Losses'] |
| 174 | + self._data['BF Paid Unpaid Claims'] = self._data['Ultimate BF Paid'] - self._data['Paid Losses'] |
114 | 175 |
|
115 | 176 | self.dataChanged.emit(index, index) |
116 | 177 | self.layoutChanged.emit() |
|
0 commit comments