From ce89db38494f93f4c0173149c5da7e7099323470 Mon Sep 17 00:00:00 2001 From: Fumito Hamamura Date: Sun, 9 Jul 2023 00:02:42 +0900 Subject: [PATCH] ENH: Add template_example2 in ifrs17a --- lifelib/libraries/ifrs17a/pnl_mapping.xlsx | Bin 14368 -> 0 bytes .../libraries/ifrs17a/template_example2.ipynb | 1657 +++++++++++++++++ makedocs/source/archive.rst | 1 + makedocs/source/libraries/ifrs17a/index.md | 14 +- .../ifrs17a/template_example2.nblink | 3 + makedocs/source/notebooks.rst | 1 + makedocs/source/releases/relnotes_v0.9.1.rst | 37 + makedocs/source/updates.rst | 5 + 8 files changed, 1712 insertions(+), 6 deletions(-) delete mode 100644 lifelib/libraries/ifrs17a/pnl_mapping.xlsx create mode 100644 lifelib/libraries/ifrs17a/template_example2.ipynb create mode 100644 makedocs/source/libraries/ifrs17a/template_example2.nblink create mode 100644 makedocs/source/releases/relnotes_v0.9.1.rst diff --git a/lifelib/libraries/ifrs17a/pnl_mapping.xlsx b/lifelib/libraries/ifrs17a/pnl_mapping.xlsx deleted file mode 100644 index 980dcdca7ff387e611c29cfbdd786b740873bb74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14368 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 N`rnEJQMO-y{Xe+i6*>R_ diff --git a/lifelib/libraries/ifrs17a/template_example2.ipynb b/lifelib/libraries/ifrs17a/template_example2.ipynb new file mode 100644 index 0000000..2ae68a4 --- /dev/null +++ b/lifelib/libraries/ifrs17a/template_example2.ipynb @@ -0,0 +1,1657 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "9604c1a4", + "metadata": {}, + "source": [ + "# Outputting Financial Performance\n", + "\n", + "This notebook is a continuation of `template_example.py` and demonstrates how the financial performance report is composed using the IFRS variables calculated by running `template.py`. The output of the financial performance table in this notebook matches the figures shown in [Systemorph's video](https://www.youtube.com/watch?v=Ud2jX3J1eNU).\n", + "\n", + "The financial performance report provides a breakdown of the total comprehensive income, as shown below. The main task in this notebook is to map various changes in balance sheet items and incurred cash flows to categories such as *Insurance Revenue* (`IR`), *Insurance Service Expense* (`ISE`), *Insurance Financial Income/Expense* (`IFIE`) or *Other Comprehensive Income* (`OCI`) within the breakdown.\n", + "\n", + "* Total Comprehensive Income\n", + "\n", + " * Profit and Loss\n", + " * Insurance Service Result\n", + " * Insurance Revenue (`IR`)\n", + " * Insurance Service Expense (`ISE`)\n", + " * Insurance Financial Income/Expense (`IFIE`)\n", + " * Other Comprehensive Income (`OCI`)\n", + " \n", + "Each item is futhur broken down as shown in the table below." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "04e43c34", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "from template import ifrsvars, workspace, AocType, EstimateType, PnlVariableType" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "836e3594", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
SystemNameDisplayName
Parent
IRIR1Premiums
IRIR2Exc. Investment Components
IRIR3CSM Amortization
IRIR4Acquistion Expenses Amortization
IRIR5Non-Financial LRC Changes (Exc. CSM Amortization)
IRIR6Exc. Experience Adjustment on Premiums
ISEISE1Reinsurance Premiums
ISEISE2Claims
ISEISE3Expenses
ISEISE4Commissions
ISEISE5Exc. Investment Components
ISEISE6Acquisition Expenses
ISEISE7Reinsurance CSM Amortization
ISEISE8LoReCo Release
ISEISE9Loss Component Release
ISEISE10Non-Financial Reinsurance LRC Changes (Exc. LC...
ISEISE11Loss Component / LoReCo Changes (Exc. Releases)
ISEISE12Non Financial LIC Changes
IFIEIFIE1Financial LRC Changes
IFIEIFIE2Financial LIC Changes
IFIEIFIE3FX Changes
OCIOCI1Financial LRC Changes
OCIOCI2Financial LIC Changes
OCIOCI3FX Changes
\n", + "
" + ], + "text/plain": [ + " SystemName DisplayName\n", + "Parent \n", + "IR IR1 Premiums\n", + "IR IR2 Exc. Investment Components\n", + "IR IR3 CSM Amortization\n", + "IR IR4 Acquistion Expenses Amortization\n", + "IR IR5 Non-Financial LRC Changes (Exc. CSM Amortization)\n", + "IR IR6 Exc. Experience Adjustment on Premiums\n", + "ISE ISE1 Reinsurance Premiums\n", + "ISE ISE2 Claims\n", + "ISE ISE3 Expenses\n", + "ISE ISE4 Commissions\n", + "ISE ISE5 Exc. Investment Components\n", + "ISE ISE6 Acquisition Expenses\n", + "ISE ISE7 Reinsurance CSM Amortization\n", + "ISE ISE8 LoReCo Release\n", + "ISE ISE9 Loss Component Release\n", + "ISE ISE10 Non-Financial Reinsurance LRC Changes (Exc. LC...\n", + "ISE ISE11 Loss Component / LoReCo Changes (Exc. Releases)\n", + "ISE ISE12 Non Financial LIC Changes\n", + "IFIE IFIE1 Financial LRC Changes\n", + "IFIE IFIE2 Financial LIC Changes\n", + "IFIE IFIE3 FX Changes\n", + "OCI OCI1 Financial LRC Changes\n", + "OCI OCI2 Financial LIC Changes\n", + "OCI OCI3 FX Changes" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pnl = workspace.database.Query(PnlVariableType, as_df=True)\n", + "pnl.loc[pnl['Parent'].isin(['IR', 'ISE', 'IFIE', 'OCI'])][\n", + " ['Parent', 'SystemName', 'DisplayName']].set_index('Parent')" + ] + }, + { + "cell_type": "markdown", + "id": "cd20153b", + "metadata": {}, + "source": [ + "## Processing Raw Data\n", + "\n", + "When the `template` module is run, all the IFRS variables become available as a DataFrame named `ifrsvars`. The `all_data` variable is then defined by filtering `ifrsvars` to only include the variables from the first quarter of 2021. `deltas` is defined to specifically include only those variables that represent increases or decreases in amounts." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "5733d4ac", + "metadata": {}, + "outputs": [], + "source": [ + "all_data = ifrsvars.loc[(ifrsvars['Year'] == 2021) & (ifrsvars['Month'] == 3)]\n", + "deltas = all_data.loc[((all_data['AocType'] != 'BOP') & (all_data['AocType'] != 'EOP')) \n", + " | ((all_data['AocType'] == 'BOP') & (all_data['Novelty'] == 'N'))]" + ] + }, + { + "cell_type": "markdown", + "id": "4f794386", + "metadata": {}, + "source": [ + "## Fulfillment Cashflows (excluding the Loss Component)\n", + "\n", + "The fulfillment cashflows comprise the best estimate liabilities (`BE`) and the risk adjustment for non-financial risk (`RA`).\n", + "\n", + "`be_or_ra` is a condition to filter `deltas` and extract variables that represent changes in `BE` and `RA`.\n", + "\n", + "Changes in the fulfillment cashflows due to the difference between current discount rates and initial(lock-in) discount rates are recognized either in Profit and Loss or in Other Comprehensive Income depending on whether the Valuation Approach is `BBA` and the OCI option is selected.\n", + "\n", + "`fcf` extracts the changes in the fulfillment cashflows that need to be measured using the lock-in discount rates,\n", + "and also the changes that need to be measured using the current discount rates.\n", + "`current_fcf` on the other hand extracts the changes using the current discount rates, regardless of the values of the valuation approaches and OCI options. The difference between `fcf` and `current_fcf` are the amounts to be recognized in `OCI`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "3c463eb6", + "metadata": {}, + "outputs": [], + "source": [ + "be_or_ra = (deltas['EstimateType'] == 'BE') | (deltas['EstimateType'] == 'RA')\n", + "as_lockin = (deltas['ValuationApproach'] == 'BBA') & deltas['OciType']\n", + "\n", + "lockin = as_lockin & (deltas['EconomicBasis'] == 'L')\n", + "current = ~as_lockin & (deltas['EconomicBasis'] == 'C')\n", + "\n", + "fcf = deltas.loc[be_or_ra & (lockin | current)]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "104ed98b", + "metadata": {}, + "outputs": [], + "source": [ + "current_fcf = deltas.loc[be_or_ra & (deltas['EconomicBasis'] == 'C')]" + ] + }, + { + "cell_type": "markdown", + "id": "8e44efe9", + "metadata": {}, + "source": [ + "### Non-Financial Component\n", + "\n", + "The non-financial component in the changes in the fulfillment cashflows is recognized as either Insurance Revenue (`IR`) or Insurance Service Result (`ISR`) in the Insurance Service Result section under Profit and Loss.\n", + "\n", + "The changes are identified by the values in the *AocType* column.\n", + "\n", + "Variables in `fcf` are split into `non_fin_fcf` and `fin_fcf` by looking at their `AocType` values." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "cd90833e", + "metadata": {}, + "outputs": [], + "source": [ + "fin_fcf_aocs = fcf['AocType'].isin(['IA', 'YCU', 'CRU', 'FX'])\n", + "non_fin_fcf_aocs = ~fin_fcf_aocs\n", + "non_fin_fcf = fcf.loc[non_fin_fcf_aocs]" + ] + }, + { + "cell_type": "markdown", + "id": "175f677e", + "metadata": {}, + "source": [ + "`non_fin_pnl_vars` is a table for mapping the non-financial changes in the fulfillment cashflows to `IR` and `ISE` items." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "c5a197e9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
LiabilityTypeIsReinsurancePnlVariableType
0LRCFalseIR5
1LRCTrueISE10
2LICFalseISE12
3LICTrueISE12
\n", + "
" + ], + "text/plain": [ + " LiabilityType IsReinsurance PnlVariableType\n", + "0 LRC False IR5\n", + "1 LRC True ISE10\n", + "2 LIC False ISE12\n", + "3 LIC True ISE12" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "non_fin_pnl_vars = pd.DataFrame.from_records(\n", + " [['LRC', False, 'IR5'],\n", + " ['LRC', True, 'ISE10'],\n", + " ['LIC', False, 'ISE12'],\n", + " ['LIC', True, 'ISE12']],\n", + " columns=['LiabilityType', 'IsReinsurance', 'PnlVariableType']\n", + ")\n", + "non_fin_pnl_vars" + ] + }, + { + "cell_type": "markdown", + "id": "4cab8389", + "metadata": {}, + "source": [ + "The code below adds the `PnlVariableType` column to `non_fin_cf` by looking up the `non_fin_pnl_vars` table, then flip the sign of the values so that the decreases in the fulfillment cashflows become positive and vice versa." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "a6f2ceb1", + "metadata": {}, + "outputs": [], + "source": [ + "non_fin_fcf = pd.merge(non_fin_fcf, non_fin_pnl_vars, how='left', on=['LiabilityType', 'IsReinsurance'], sort=False)\n", + "non_fin_fcf['Value'] = -1 * non_fin_fcf['Value']" + ] + }, + { + "cell_type": "markdown", + "id": "26e2b543", + "metadata": {}, + "source": [ + "### Financial Component\n", + "\n", + "The non-financial component in the changes in the fulfillment cashflows \n", + "`fin_pnl_vars` is a mapping table for the financial component." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "dc0f0309", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
LiabilityTypePnlVariableType
0LRCIFIE1
1LICIFIE2
\n", + "
" + ], + "text/plain": [ + " LiabilityType PnlVariableType\n", + "0 LRC IFIE1\n", + "1 LIC IFIE2" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fin_pnl_vars = pd.DataFrame.from_records(\n", + " [['LRC', 'IFIE1'],\n", + " ['LIC', 'IFIE2']],\n", + " columns=['LiabilityType', 'PnlVariableType']\n", + ")\n", + "fin_pnl_vars" + ] + }, + { + "cell_type": "markdown", + "id": "8b6b5b12", + "metadata": {}, + "source": [ + "`fin_fcf` is defined by extracting variables that have financial AoC types.\n", + "The code below adds the `PnlVariableType` column to `fin_fcf` by looking up the `fin_pnl_vars` table, then flip the sign of the values so that the decreases in the fulfillment cashflows become positive and vice versa." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "2e4f7e70", + "metadata": {}, + "outputs": [], + "source": [ + "fin_fcf = fcf.loc[fin_fcf_aocs]\n", + "fin_fcf = pd.merge(fin_fcf, fin_pnl_vars, how='left', on='LiabilityType', sort=False)\n", + "fin_fcf['Value'] = -1 * fin_fcf['Value']" + ] + }, + { + "cell_type": "markdown", + "id": "098a1e83", + "metadata": {}, + "source": [ + "### OCI Component\n", + "\n", + "`oci_vars` is a mapping table for the OCI component in the fulfillment cashflows. " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "f04da2c4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
LiabilityTypePnlVariableType
0LRCOCI1
1LICOCI2
\n", + "
" + ], + "text/plain": [ + " LiabilityType PnlVariableType\n", + "0 LRC OCI1\n", + "1 LIC OCI2" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "oci_vars = pd.DataFrame.from_records(\n", + " [['LRC', 'OCI1'],\n", + " ['LIC', 'OCI2']],\n", + " columns=['LiabilityType', 'PnlVariableType']\n", + ")\n", + "oci_vars" + ] + }, + { + "cell_type": "markdown", + "id": "3dda3c55", + "metadata": {}, + "source": [ + "For the groups of contracts with the OCI option, the changes in the fulfillment cashflows due to the difference between current discount rates and initial(lock-in) discount rates are recognized in Other Comprehensive Income.\n", + "\n", + "The code below captures the difference.\n", + "`current_fcf` is copied as `current_fcf_n` and the sings of the values are flipped in `current_fcf_n`.\n", + "`oci_fin` below is created by concatinating `current_fcf_n` and `fcf`.\n", + "`PnlVariableType` column is added to `oci_fin` by looking up the `oci_vars` table." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "5f6d237f", + "metadata": {}, + "outputs": [], + "source": [ + "current_fcf_n = current_fcf.copy()\n", + "current_fcf_n['Value'] = -1 * current_fcf['Value']\n", + "oci_fin = pd.merge(pd.concat([fcf, current_fcf_n]), oci_vars, how='left', on='LiabilityType', sort=False)" + ] + }, + { + "cell_type": "markdown", + "id": "18ac082e", + "metadata": {}, + "source": [ + "### Change in Fulfillment Cashflows\n", + "\n", + "The last step in processing the changes in fulfillment cashflows is to concatinate the 3 components, `non_fin_fcf`, `fin_fcf` and `oci_fin`." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "36082ecc", + "metadata": {}, + "outputs": [], + "source": [ + "fcf_chg_in_est = pd.concat([non_fin_fcf, fin_fcf, oci_fin])" + ] + }, + { + "cell_type": "markdown", + "id": "62cea410", + "metadata": {}, + "source": [ + "## Contractual Service Margin (CSM)\n", + "\n", + "CSM changes can be extracted from `deltas` by filtering the `EstimateType` column for rows marked as `C`." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "86ca2fa7", + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "csm = deltas.loc[deltas['EstimateType'] == 'C']" + ] + }, + { + "cell_type": "markdown", + "id": "2a98c788", + "metadata": {}, + "source": [ + "To map the IFRS variables, which indicate CSM changes, to the Financial Performance items, we first map the `AocType` values to `PnlType` using the `csm_type` table. The `PnlType` values can be either `NF`, `F`, `AM`, or `FX`, where `NF` represents non-financial, `F` represents financial, `AM` stands for amortization, and `FX` means foreign exchange. The changes are then mapped to the Financial Performance items using the `csm_vars` table based on the `PnlType` values and the values in the `IsReinsurance` column.\n", + "\n", + "Lastly, the signs of the variable values are inverted to ensure decreases in CSM are represented as positive and increases are represented as negative." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "02786c3f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
AocTypePnlType
0BOPNF
1MCNF
2PCNF
3RCUNF
4CFNF
5IAF
6AUNF
7FAUF
8YCUF
9CRUF
10EVNF
11WONF
12CLNF
13EANF
14AMAM
15FXFX
16EOPNone
\n", + "
" + ], + "text/plain": [ + " AocType PnlType\n", + "0 BOP NF\n", + "1 MC NF\n", + "2 PC NF\n", + "3 RCU NF\n", + "4 CF NF\n", + "5 IA F\n", + "6 AU NF\n", + "7 FAU F\n", + "8 YCU F\n", + "9 CRU F\n", + "10 EV NF\n", + "11 WO NF\n", + "12 CL NF\n", + "13 EA NF\n", + "14 AM AM\n", + "15 FX FX\n", + "16 EOP None" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "aoc_to_pnl_type = workspace.database.Query(AocType, as_df=True).rename(\n", + " columns={'SystemName': 'AocType'})[['AocType', 'PnlType']]\n", + "aoc_to_pnl_type" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "34a12b9c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
PnlTypeIsReinsurancePnlVariableType
0NFFalseIR5
1NFTrueISE10
2FFalseIFIE1
3FTrueIFIE1
4AMFalseIR3
5AMTrueISE7
6FXFalseIFIE3
7FXTrueIFIE3
\n", + "
" + ], + "text/plain": [ + " PnlType IsReinsurance PnlVariableType\n", + "0 NF False IR5\n", + "1 NF True ISE10\n", + "2 F False IFIE1\n", + "3 F True IFIE1\n", + "4 AM False IR3\n", + "5 AM True ISE7\n", + "6 FX False IFIE3\n", + "7 FX True IFIE3" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "csm_vars = pd.DataFrame.from_records(\n", + " [['NF', False, 'IR5'],\n", + " ['NF', True, 'ISE10'],\n", + " ['F', False, 'IFIE1'],\n", + " ['F', True, 'IFIE1'],\n", + " ['AM', False, 'IR3'],\n", + " ['AM', True, 'ISE7'],\n", + " ['FX', False, 'IFIE3'],\n", + " ['FX', True, 'IFIE3']],\n", + " columns=['PnlType', 'IsReinsurance', 'PnlVariableType']\n", + ")\n", + "csm_vars" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "11d51095", + "metadata": {}, + "outputs": [], + "source": [ + "csm_chg_in_est = pd.merge(\n", + " pd.merge(csm, aoc_to_pnl_type, how='left', on='AocType', sort=False), \n", + " csm_vars, on=['PnlType', 'IsReinsurance'], sort=False)\n", + "csm_chg_in_est['Value'] = -1 * csm_chg_in_est['Value']" + ] + }, + { + "cell_type": "markdown", + "id": "15eda8b7", + "metadata": {}, + "source": [ + "## Loss Component (LC)\n", + "\n", + "The changes in Loss Component are mapped by the same steps as CSM:\n", + "- Fitering `deltas` by `deltas['EstimateType'] == 'L'`\n", + "- Mapping *AocType* to *PnlType*\n", + "- Mapping *PnlType* to *PnlVariableType*" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "2e9a58fc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
PnlTypePnlVariableType
0NFISE11
1FIFIE1
2AMISE9
3FXIFIE3
\n", + "
" + ], + "text/plain": [ + " PnlType PnlVariableType\n", + "0 NF ISE11\n", + "1 F IFIE1\n", + "2 AM ISE9\n", + "3 FX IFIE3" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lc = deltas.loc[deltas['EstimateType'] == 'L']\n", + "lc_vars = pd.DataFrame.from_records(\n", + " [['NF','ISE11'],\n", + " ['F', 'IFIE1'],\n", + " ['AM','ISE9'],\n", + " ['FX','IFIE3']],\n", + " columns=['PnlType', 'PnlVariableType']\n", + ")\n", + "lc_vars" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "41a0c12a", + "metadata": {}, + "outputs": [], + "source": [ + "lc_chg_in_est = pd.merge(\n", + " pd.merge(lc, aoc_to_pnl_type, how='left', on='AocType', sort=False),\n", + " lc_vars, on='PnlType', sort=False)\n", + "lc_chg_in_est['Value'] = -1 * lc_chg_in_est['Value']" + ] + }, + { + "cell_type": "markdown", + "id": "352b43ac", + "metadata": {}, + "source": [ + "## Loss Recovery Component (LoReCo)\n", + "\n", + "\n", + "The changes in Loss Recovery Component are mapped by the same steps as CSM and Locc Component:\n", + "- Fitering `deltas` by `deltas['EstimateType'] == 'LR'`\n", + "- Mapping *AocType* to *PnlType*\n", + "- Mapping *PnlType* to *PnlVariableType*\n", + "- Inverting the values" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "84d27943", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
PnlTypePnlVariableType
0NFISE11
1FIFIE1
2AMISE8
3FXIFIE3
\n", + "
" + ], + "text/plain": [ + " PnlType PnlVariableType\n", + "0 NF ISE11\n", + "1 F IFIE1\n", + "2 AM ISE8\n", + "3 FX IFIE3" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lrc = deltas.loc[deltas['EstimateType'] == 'LR']\n", + "lrc_vars = pd.DataFrame.from_records(\n", + " [['NF','ISE11'],\n", + " ['F', 'IFIE1'],\n", + " ['AM','ISE8'],\n", + " ['FX','IFIE3']],\n", + " columns=['PnlType', 'PnlVariableType']\n", + ")\n", + "lrc_vars" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "f01cb5b6", + "metadata": {}, + "outputs": [], + "source": [ + "lrc_chg_in_est = pd.merge(pd.merge(lrc, aoc_to_pnl_type, how='left', on='AocType', sort=False), lrc_vars, on='PnlType', sort=False)\n", + "lrc_chg_in_est['Value'] = -1 * lrc_chg_in_est['Value']" + ] + }, + { + "cell_type": "markdown", + "id": "1c8c2539", + "metadata": {}, + "source": [ + "## Incurred Actuals\n", + "\n", + "Next, variables of actual cashflows are processed according to the following steps:\n", + "\n", + "- Variables for incurred cashflows are extracted from `deltas` by looking at their EstimateType and AocType\n", + "- Premium cashflows are extracted as `premiums` and mapped to either `IR` or `ISE`\n", + "- Non-investment component claims are extracted as `claims_nic` and mapped to Insurance Service Expense\n", + "- Investment-component claims are extracted as `claims_ico_ir` and `claims_ico_ise`, and are then recognized in the `IR` and `ISE` respectively. The values in `claims_ico_ise` are inverted so that they negate each other.\n", + "- `expenses`, `commissions` are also defined and mapped to respective Insurance Service Expense items.\n", + "- `incurred_actuals` is defined by concatinating `premiums`, `claims_nic`, `claims_ico_ir`, `claims_ico_ise`, `expenses`, and `commissions`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "f4ec8197", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "written_cf = (deltas['EstimateType'] == 'A') & (deltas['AocType']=='CF')\n", + "advanced_wo = (deltas['EstimateType'] == 'AA') & (deltas['AocType']=='WO')\n", + "overdue_wo = (deltas['EstimateType'] == 'OA') & (deltas['AocType']=='WO')\n", + "\n", + "actuals_data = deltas.loc[written_cf | advanced_wo | overdue_wo]\n", + "actuals_data.loc[actuals_data['AocType'] == 'WO', 'Value'] *= -1" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "5e8fb1f4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
IsReinsurancePnlVariableType
0FalseIR1
1TrueISE1
\n", + "
" + ], + "text/plain": [ + " IsReinsurance PnlVariableType\n", + "0 False IR1\n", + "1 True ISE1" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "prem_vars = pd.DataFrame.from_records(\n", + " [[False,'IR1'],\n", + " [True, 'ISE1']],\n", + " columns=['IsReinsurance', 'PnlVariableType']\n", + ")\n", + "prem_vars" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "1bb1ab8e", + "metadata": {}, + "outputs": [], + "source": [ + "premiums = pd.merge(actuals_data.loc[\n", + " (actuals_data['AmountType']=='PR')], prem_vars, how='left', on='IsReinsurance', sort=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "fe899162", + "metadata": {}, + "outputs": [], + "source": [ + "claims_nic = actuals_data.loc[(actuals_data['AmountType']=='NIC')].copy()\n", + "claims_nic['PnlVariableType'] = 'ISE2'" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "69b7dace", + "metadata": {}, + "outputs": [], + "source": [ + "claims_ico_ir = actuals_data.loc[(actuals_data['AmountType']=='ICO')].copy()\n", + "claims_ico_ise = claims_ico_ir.copy()\n", + "claims_ico_ir['PnlVariableType'] = 'IR2'\n", + "claims_ico_ise['PnlVariableType'] = 'ISE5'\n", + "claims_ico_ise['Value'] = -1 * claims_ico_ise['Value']" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "bca3fc7b", + "metadata": {}, + "outputs": [], + "source": [ + "expenses = actuals_data.loc[\n", + " (actuals_data['AmountType']=='AEA') | (actuals_data['AmountType']=='AEM')\n", + "].copy()\n", + "expenses['PnlVariableType'] = 'ISE3'" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "67cc2543", + "metadata": {}, + "outputs": [], + "source": [ + "commissions = actuals_data.loc[\n", + " (actuals_data['AmountType']=='ACA') | (actuals_data['AmountType']=='ACM')\n", + "].copy()\n", + "commissions['PnlVariableType'] = 'ISE4'" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "4e0563c2", + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "incurred_actuals = pd.concat([\n", + " premiums, claims_nic, claims_ico_ir, claims_ico_ise, expenses, commissions])" + ] + }, + { + "cell_type": "markdown", + "id": "03a923b7", + "metadata": {}, + "source": [ + "## Incurred Deferrals and Acquisition Expenses\n", + "\n", + "`incurred_deferrals` include variables related to acquisition expense amortization.\n", + "Amortized acquisition expenses are shown both in Insurance Revenue and Insurance Service Expense." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "fcad9e33", + "metadata": {}, + "outputs": [], + "source": [ + "amort = deltas.loc[(deltas['EstimateType'] == 'DA') & (deltas['AocType'] == 'AM')]\n", + "amort_ir = amort.copy()\n", + "amort_ise = amort.copy()\n", + "\n", + "amort_ir['PnlVariableType'] = 'IR4'\n", + "amort_ise['PnlVariableType'] = 'ISE6'\n", + "\n", + "amort_ise['Value'] = -1 * amort_ise['Value']\n", + "\n", + "incurred_deferrals = pd.concat([amort_ir, amort_ise])" + ] + }, + { + "cell_type": "markdown", + "id": "d5f91d9f", + "metadata": {}, + "source": [ + "## Experience Adjustment on Premium (allocation to CSM vs P&L recognition)\n", + "\n", + "Experience adjustments related to premium receipts for current and past periods should be included in insurance revenue.\n", + "The following code creates `exp_adjust_prem`, which adjust Insurance Revenue for the experience adjustment on premiums." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "e18ca188", + "metadata": {}, + "outputs": [], + "source": [ + "act_prem_csm = all_data.loc[all_data['EstimateType'] == 'APA'].copy()\n", + "act_prem_csm['Value'] = -1 * act_prem_csm['Value']\n", + "act_prem_csm['PnlVariableType'] = 'IR6'\n", + "\n", + "est_prem_csm = deltas.loc[deltas['EstimateType'] == 'BEPA'].copy()\n", + "est_prem_csm['PnlVariableType'] = 'IR6'\n", + "\n", + "exp_adjust_prem = pd.concat([act_prem_csm, est_prem_csm])" + ] + }, + { + "cell_type": "markdown", + "id": "3d543540", + "metadata": {}, + "source": [ + "## Financial Performance\n", + "\n", + "Finally, we create the `financial_performance` table by concatenating all the previously created tables. We then manipulate this combined table through grouping, summing, and reshaping operations to arrive at the final form of the financial performance table." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "2735b936", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Value
LiabilityTypeLICLRC
PnlVariableType
IFIE10.000000-0.250282
IFIE2-1.2407560.000000
IR10.000000613.000000
IR20.000000-42.000000
IR30.00000063.519146
IR40.00000059.158616
IR50.00000038.096408
IR60.000000182.000000
ISE10.000000-183.500000
ISE100.00000072.607574
ISE110.000000-8.063094
ISE1237.1113260.000000
ISE2-82.000000-367.500000
ISE30.000000-35.000000
ISE40.000000-70.000000
ISE50.00000042.000000
ISE60.000000-59.158616
ISE70.000000-44.532586
ISE90.0000008.128297
OCI10.000000-0.006156
OCI20.1838080.000000
\n", + "
" + ], + "text/plain": [ + " Value \n", + "LiabilityType LIC LRC\n", + "PnlVariableType \n", + "IFIE1 0.000000 -0.250282\n", + "IFIE2 -1.240756 0.000000\n", + "IR1 0.000000 613.000000\n", + "IR2 0.000000 -42.000000\n", + "IR3 0.000000 63.519146\n", + "IR4 0.000000 59.158616\n", + "IR5 0.000000 38.096408\n", + "IR6 0.000000 182.000000\n", + "ISE1 0.000000 -183.500000\n", + "ISE10 0.000000 72.607574\n", + "ISE11 0.000000 -8.063094\n", + "ISE12 37.111326 0.000000\n", + "ISE2 -82.000000 -367.500000\n", + "ISE3 0.000000 -35.000000\n", + "ISE4 0.000000 -70.000000\n", + "ISE5 0.000000 42.000000\n", + "ISE6 0.000000 -59.158616\n", + "ISE7 0.000000 -44.532586\n", + "ISE9 0.000000 8.128297\n", + "OCI1 0.000000 -0.006156\n", + "OCI2 0.183808 0.000000" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "financial_performance = pd.concat([\n", + " fcf_chg_in_est, \n", + " csm_chg_in_est, \n", + " lc_chg_in_est, \n", + " lrc_chg_in_est, \n", + " incurred_actuals, \n", + " incurred_deferrals, \n", + " exp_adjust_prem])\n", + "\n", + "financial_performance[\n", + " ['Value', 'LiabilityType', 'PnlVariableType']\n", + " ].groupby(\n", + " ['LiabilityType', 'PnlVariableType']).sum().unstack(level=[0]).fillna(0)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/makedocs/source/archive.rst b/makedocs/source/archive.rst index c378ef8..0cd91ee 100644 --- a/makedocs/source/archive.rst +++ b/makedocs/source/archive.rst @@ -11,6 +11,7 @@ Past Documents .. raw:: html
    +
  • lifelib v0.9.0
  • lifelib v0.8.1
  • lifelib v0.8.0
  • lifelib v0.7.0
  • diff --git a/makedocs/source/libraries/ifrs17a/index.md b/makedocs/source/libraries/ifrs17a/index.md index 288dbab..78be494 100644 --- a/makedocs/source/libraries/ifrs17a/index.md +++ b/makedocs/source/libraries/ifrs17a/index.md @@ -74,13 +74,15 @@ To create *myifrs17* in the current directory, type: This library includes the following Jupyter Notebooks: * {doc}`template_example` +* {doc}`template_example2` * {doc}`present_value_example_ep2` * {doc}`present_value_example_ep3` * {doc}`logic_inspection_example` -Each of the first three notebooks runs a corresponding Python script, -such `template.py`, `present_value_ep2.py` and `present_value_ep3.py`, -and reproduces tables presented in Systemorph's videos. +The first two notebooks run `template.py`, +and the next two notebooks run `present_value_ep2.py` and +`present_value_ep3.py` respectively, +and reproduce tables presented in Systemorph's videos. The last notebook demonstrates how to inspect the calculation logic. To run any of the Jupyter notebooks, the current directory @@ -101,7 +103,7 @@ and try inserting '' in the list. As mentioned above, this library includes the following Python scripts: -* template_example.py +* template.py * present_value_ep2.py * present_value_ep3.py @@ -248,11 +250,10 @@ For more detailed explanations, refer to the original documentation linked above | present_value_ep2.py | Python script for present value episode 2 example | | present_value_ep3.py | Python script for present value episode 3 exmaple | | {doc}`template_example.ipynb` | Jupyter notebook to reproduce tables of template example | +| {doc}`template_example2.ipynb` | Jupyter notebook to reproduce the Financial Performance report | | {doc}`present_value_example_ep2.ipynb` | Jupyter notebook to reproduce tables of present value example episode 2 | | {doc}`present_value_example_ep3.ipynb` | Jupyter notebook to reproduce tables of present value example episode 3 | | {doc}`logic_inspection_example.ipynb` | Jupyter notebook showing how to inspect the calculation logic | -| pnl_mapping.xlsx | Excel file showing how to map IfrsVariables to P&L items | - ## String Keys @@ -419,6 +420,7 @@ generated by the scripts. Below are the classes and their string keys. hidden: --- template_example +template_example2 present_value_example_ep2 present_value_example_ep3 logic_inspection_example diff --git a/makedocs/source/libraries/ifrs17a/template_example2.nblink b/makedocs/source/libraries/ifrs17a/template_example2.nblink new file mode 100644 index 0000000..da26914 --- /dev/null +++ b/makedocs/source/libraries/ifrs17a/template_example2.nblink @@ -0,0 +1,3 @@ +{ + "path": "../../../../lifelib/libraries/ifrs17a/template_example2.ipynb" +} \ No newline at end of file diff --git a/makedocs/source/notebooks.rst b/makedocs/source/notebooks.rst index 0afc504..a82d126 100644 --- a/makedocs/source/notebooks.rst +++ b/makedocs/source/notebooks.rst @@ -33,6 +33,7 @@ Notebooks --------------------------- * :doc:`libraries/ifrs17a/template_example` +* :doc:`libraries/ifrs17a/template_example2` * :doc:`libraries/ifrs17a/present_value_example_ep2` * :doc:`libraries/ifrs17a/present_value_example_ep3` * :doc:`libraries/ifrs17a/logic_inspection_example` diff --git a/makedocs/source/releases/relnotes_v0.9.1.rst b/makedocs/source/releases/relnotes_v0.9.1.rst new file mode 100644 index 0000000..f128462 --- /dev/null +++ b/makedocs/source/releases/relnotes_v0.9.1.rst @@ -0,0 +1,37 @@ +.. currentmodule:: lifelib.libraries + +.. _relnotes_v0.9.1: + +================================== +lifelib v0.9.1 (8 July 2023) +================================== + +This release adds a new notebook, :doc:`/libraries/ifrs17a/template_example2` in +the :mod:`~ifrs17a` library, and fixes some bugs. + +To update lifelib, run the following command:: + + >>> pip install lifelib --upgrade + +If you're using Anaconda, use the ``conda`` command instead:: + + >>> conda update lifelib + + +Updates in :mod:`~ifrs17a` +=========================== + +* A new notebook, :doc:`/libraries/ifrs17a/template_example2` is added. +* A new column, *PnlType* is added to the *AocType* table in *Dimension.xlsx* +* ``IfrsDatabase.Query`` now optionally takes a boolean parameter `as_df` to indicate + whether to return the query result as a DataFrame. +* Fixed multiplier in *ImportScopeCalculation.py*. + +.. seealso:: + + * `Systemorph's video on IFRS17 Profit and loss statement `_ + + + + + diff --git a/makedocs/source/updates.rst b/makedocs/source/updates.rst index 0d06990..74fa13d 100644 --- a/makedocs/source/updates.rst +++ b/makedocs/source/updates.rst @@ -14,6 +14,11 @@ Updates Follow lifelib on LinkedIn for more frequent updates.

    +* *8 July 2023:* + lifelib v0.9.1 is released. + a new notebook, :doc:`/libraries/ifrs17a/template_example2` is added in :mod:`~ifrs17a`. + See :ref:`Release Notes` for details. + * *13 May 2023:* lifelib v0.9.0 is released. :mod:`~ifrs17a`, a new library for IFRS 17 is added. See :ref:`Release Notes` for details.