diff --git a/PresentValueSeries/CF_CH_2021_12.xlsx b/PresentValueSeries/CF_CH_2021_12.xlsx new file mode 100644 index 00000000..bdc502b9 Binary files /dev/null and b/PresentValueSeries/CF_CH_2021_12.xlsx differ diff --git a/PresentValueSeries/CF_DE_2021_12.xlsx b/PresentValueSeries/CF_DE_2021_12.xlsx new file mode 100644 index 00000000..72fb2aff Binary files /dev/null and b/PresentValueSeries/CF_DE_2021_12.xlsx differ diff --git a/PresentValueSeries/CF_DE_2022_12.xlsx b/PresentValueSeries/CF_DE_2022_12.xlsx new file mode 100644 index 00000000..fe5e13b8 Binary files /dev/null and b/PresentValueSeries/CF_DE_2022_12.xlsx differ diff --git a/PresentValueSeries/Cashflows.xlsx b/PresentValueSeries/Cashflows.xlsx new file mode 100644 index 00000000..1b1ffd52 Binary files /dev/null and b/PresentValueSeries/Cashflows.xlsx differ diff --git a/PresentValueSeries/DataNodes.xlsx b/PresentValueSeries/DataNodes.xlsx new file mode 100644 index 00000000..6ae13a45 Binary files /dev/null and b/PresentValueSeries/DataNodes.xlsx differ diff --git a/PresentValueSeries/DataNodes_CH.xlsx b/PresentValueSeries/DataNodes_CH.xlsx new file mode 100644 index 00000000..794df062 Binary files /dev/null and b/PresentValueSeries/DataNodes_CH.xlsx differ diff --git a/PresentValueSeries/DataNodes_DE.xlsx b/PresentValueSeries/DataNodes_DE.xlsx new file mode 100644 index 00000000..32e40f55 Binary files /dev/null and b/PresentValueSeries/DataNodes_DE.xlsx differ diff --git a/PresentValueSeries/Dimensions.xlsx b/PresentValueSeries/Dimensions.xlsx new file mode 100644 index 00000000..806a6c76 Binary files /dev/null and b/PresentValueSeries/Dimensions.xlsx differ diff --git a/PresentValueSeries/Images/PvFlowchart.png b/PresentValueSeries/Images/PvFlowchart.png new file mode 100644 index 00000000..156bdf4c Binary files /dev/null and b/PresentValueSeries/Images/PvFlowchart.png differ diff --git a/PresentValueSeries/Images/PvOverview.png b/PresentValueSeries/Images/PvOverview.png new file mode 100644 index 00000000..38ea7b38 Binary files /dev/null and b/PresentValueSeries/Images/PvOverview.png differ diff --git a/PresentValueSeries/Images/PvWaterfallChart.png b/PresentValueSeries/Images/PvWaterfallChart.png new file mode 100644 index 00000000..4a88ff0e Binary files /dev/null and b/PresentValueSeries/Images/PvWaterfallChart.png differ diff --git a/PresentValueSeries/Images/SM-Thumbnail-S01-288x142.png b/PresentValueSeries/Images/SM-Thumbnail-S01-288x142.png new file mode 100644 index 00000000..1f4c6992 Binary files /dev/null and b/PresentValueSeries/Images/SM-Thumbnail-S01-288x142.png differ diff --git a/PresentValueSeries/Images/SM-YoutubePreview-S01E01.png b/PresentValueSeries/Images/SM-YoutubePreview-S01E01.png new file mode 100644 index 00000000..f8547337 Binary files /dev/null and b/PresentValueSeries/Images/SM-YoutubePreview-S01E01.png differ diff --git a/PresentValueSeries/Images/SM-YoutubePreview-S01E02.png b/PresentValueSeries/Images/SM-YoutubePreview-S01E02.png new file mode 100644 index 00000000..7d36967c Binary files /dev/null and b/PresentValueSeries/Images/SM-YoutubePreview-S01E02.png differ diff --git a/PresentValueSeries/Images/SM-YoutubePreview-S01E03.png b/PresentValueSeries/Images/SM-YoutubePreview-S01E03.png new file mode 100644 index 00000000..86023f84 Binary files /dev/null and b/PresentValueSeries/Images/SM-YoutubePreview-S01E03.png differ diff --git a/PresentValueSeries/Images/Systemorph_logo.png b/PresentValueSeries/Images/Systemorph_logo.png new file mode 100644 index 00000000..402f8cfb Binary files /dev/null and b/PresentValueSeries/Images/Systemorph_logo.png differ diff --git a/PresentValueSeries/Images/VanessaAndrea.png b/PresentValueSeries/Images/VanessaAndrea.png new file mode 100644 index 00000000..1c0dcd82 Binary files /dev/null and b/PresentValueSeries/Images/VanessaAndrea.png differ diff --git a/PresentValueSeries/InitializeData.ipynb b/PresentValueSeries/InitializeData.ipynb new file mode 100644 index 00000000..8fc5e0c7 --- /dev/null +++ b/PresentValueSeries/InitializeData.ipynb @@ -0,0 +1,96 @@ +{ + "metadata": { + "authors": [], + "kernelspec": { + "display_name": "Formula Framework", + "language": "C#", + "name": "C#" + }, + "language_info": { + "file_extension": ".cs", + "mimetype": "text/plain", + "name": "C#" + }, + "toc-autonumbering": "True", + "toc-showcode": "False", + "toc-showmarkdowntxt": "False", + "toc-showtags": "False" + }, + "nbformat": 4, + "nbformat_minor": 5, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "

Initialize Dimensions

" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "---" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Import.FromFile(\"Dimensions.xlsx\")", + "\n .WithType() .WithType() .WithType()", + "\n .WithType() .WithType() .WithType()", + "\n .WithType() .WithType() .WithType()", + "\n .WithType() .WithType() .WithType()", + "\n .WithType() .WithType() .WithType()", + "\n .WithType() .WithType() .WithType() ", + "\n .WithType()", + "\n .WithTarget(DataSource)", + "\n .ExecuteAsync()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Import.FromFile(\"Dimensions.xlsx\").WithFormat(ImportFormats.AocConfiguration).WithTarget(DataSource).ExecuteAsync()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Import.FromFile(\"DataNodes.xlsx\").WithFormat(\"DataNode\").WithTarget(DataSource).ExecuteAsync()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "Workspace.Reset(x => x.ResetInitializationRules());", + "\nWorkspace.InitializeFrom(DataSource);" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/PresentValueSeries/PresentValue - Episode 2.ipynb b/PresentValueSeries/PresentValue - Episode 2.ipynb new file mode 100644 index 00000000..f893df08 --- /dev/null +++ b/PresentValueSeries/PresentValue - Episode 2.ipynb @@ -0,0 +1,482 @@ +{ + "metadata": { + "authors": [], + "kernelspec": { + "display_name": "Formula Framework", + "language": "C#", + "name": "C#" + }, + "language_info": { + "file_extension": ".cs", + "mimetype": "text/plain", + "name": "C#" + }, + "toc-autonumbering": "True", + "toc-showcode": "False", + "toc-showmarkdowntxt": "False", + "toc-showtags": "False" + }, + "nbformat": 4, + "nbformat_minor": 5, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "

How to compute Present Values

" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "> IFRS 17 is a new accounting standard for insurance contracts. It is an economic accounting approach, replacing the nominal accounting of the previous standard IFRS 4, that is, the economic value of the insurance products is considered. The focus is on the liabilities of an insurance company, namely the insurance policies. ", + "\n", + "\n

" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "
", + "\n", + "\nThe aim of this notebook is to illustrate the IFRS 17 *Present Value* calculation using Systemorph Cloud Technology. Present Values are the amount of money that someone would pay in the present day for the contracts of the group up to their run off. The starting point are the so called *Nominal Cash flows*, which express the amounts of cash and cash equivalents being transferred into and out of a business. Cash flow values are **discounted** according to the *Yield Curve* provided as economic input in order to take into account the corresponding Interest Accretion, and the discounted figures are **cumulated** to find the **Present Values**. ", + "\n", + "\nThe IFRS 17 standard prescribes that the accounting statements are based on the value of a group of insurance contracts at the beginning of the period (BoP), their development throughout the period, and the value at the end of the period (EoP). While the period is typically a quarter, the **Analysis of Change** (AoC) from BoP to EoP per group of contract is made considering for each step the variation of the cashflow so as to enhance the readability of the value changes. To this aim it is necessary to **evaluate the Present Value difference** (or delta) between each step, yielding the figures shown in the resulting report.", + "\n", + "\nThis process is pictorially represented in the flowchart below" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "
" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "---", + "\n", + "\nImport the IFRS17 calculation engine:" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "#!import \"//ifrs17/v1.0.0/CalculationEngine\"" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Initialize basic pre-configured dimensions that can be tuned to reflect for your company and business. Example of such dimensions are", + "\n", + "\n**Reporting Nodes**: hierarchical structure of the company, where the root is the *Group* level and the end nodes are the levels at which data is imported.", + "\n", + "\n**Data Nodes**: Grouping of (Re-)Insurance Contracts belonging to the same Portfolio, and defined by their Reporting Node, Scenario, Contractual Currency, FunctionalCurrency, LineOfBusiness, ValuationApproach, and OCI Type. ", + "\n", + "\n**Aoc Type**: the Analysis of Change steps used for accounting statements." + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "#!eval-notebook \"InitializeData\"" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "---" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Import" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "In the following code cells, the necessary data to start the IFRS calculator are being imported.", + "\nAfter the standard dimensions and parameters are loaded, for the calculation of the Present Value ", + "\none needs the economic input yield curves for the target period", + "\nand the nominal cashflows for the desired group of contracts:", + "\n", + "\n**Yield Curve**: line that plots yields, i.e. interest rates. It depends on the given currency related to the target *Reporting Node*, and is imported on a yierly basis. The slope of the yield curve gives an idea of future interest rate changes and economic activity.", + "\n", + "\n**Nominal Cashflows**: they are the amounts of cash and cash equivalents that a company expects to transfer into and out of a business, without any adjustment. This is useful for anticipating future revenue and expenses.", + "\n", + "\nThe import process of these example spreadsheets can be completed by running the two cells below" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Import.FromFile(\"YieldCurve.xlsx\").WithType().WithTarget(DataSource).ExecuteAsync()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Import.FromFile(\"Cashflows.xlsx\").WithFormat(\"Cashflow\").WithTarget(DataSource).ExecuteAsync()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "



", + "\n", + "\n", + "\n# Present Value Report" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Present Value is today’s value of money you expect from future income and is calculated as the sum of future investment returns discounted at a specified level of rate of return expectation.", + "\n", + "\nThe change of the Present Value in the target period is analysed following the Analysis of Change method." + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var pv = ifrs17.PresentValues;" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "pv.ReportingNode = \"G\";", + "\npv.ReportingPeriod = (2021, 3);", + "\npv.ColumnSlices = new[] {\"EstimateType\", \"AmountType\"};", + "\npv.DataFilter = new[] {(\"EconomicBasis\", \"L\")};" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await pv.ToReportAsync" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "














", + "\n", + "\n# View imported Data" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Systemorph notebook technology excels in analyse on the fly the imported data. In this section the newly imported Yield Curves and nominal cashflows can be analysed." + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "**Imported Yield Curve**" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var yieldCurves = await DataSource.Query().ToArrayAsync();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Report.ForDataCube(yieldCurves.ToReportType()).SliceRowsBy(\"Currency\").SliceColumnsBy(\"Index\").ToLineChart().ExecuteAsync() with { Width = 1000 }" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "**Imported Nominal Cashflows**" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var nominals = (await DataSource.Query().ToArrayAsync()).ToDataCube();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Report.ForDataCube(nominals.ToReportType()).SliceRowsBy(\"AmountType\",\"AocType\").SliceColumnsBy(\"Index\").WithQuerySource(Workspace).ToBarChart().ExecuteAsync()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Discounting and Cumulate" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "The list of **Amount Types** are retrieved from the Data Source" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var amountTypes = await DataSource.Query().ToArrayAsync();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "The **Yield Curve** associated to the target Group of Contract Reporting Node Currency is selected for the computation of the Discount rates", + "\n", + "\n$$", + "\n\\text{Discount}_i = \\big( 1 + \\text{YieldCurve}_i \\big) ^{-\\frac{1}{12}} ~.", + "\n$$" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var discountRates = ( from yc in yieldCurves.FirstOrDefault(x => x.Currency == \"CHF\").Values select Math.Pow( 1 + yc, - 1.0 / 12.0 ) ).ToArray();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "The Cumulated Discounted Cashflow ($\\text{CDC}$) is defined by the following recursive formulas", + "\n", + "\n$$", + "\n\\text{CDC}_t = \\left\\{", + "\n\\begin{array}{cl}", + "\n\\text{Nominal}_t + \\text{CDC}_{t+1} \\cdot {\\text{Valid Discount}_{\\frac{t}{12}}} ~, & \\text{if Period Type is Beginning of Period} \\\\", + "\n\\big( \\text{Nominal}_t + \\text{CDC}_{t+1} \\big) \\cdot {\\text{Valid Discount}_{\\frac{t}{12}}} ~, & \\text{if Period Type is End of Period}", + "\n\\end{array}", + "\n\\right.", + "\n$$", + "\n", + "\nwhere the Period Type depends on the given cashflow Amount Type. " + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "In the following, the premiums are retrieved from the nominals **Data Cube** through a simple Filter. ", + "\nAdditionally, among the list of premiums provided, we select only the cashflows for the Assumption Update (AU) and Experience Variance (EV) steps." + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "The discount and cumulation operation can be performed on the resulting Data Cube through the method ComputeDiscountAndCumulateAsync provided by the solution. We focus on the Assumption Update step" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var premiumsAU = nominals.Filter((\"AmountType\", \"PR\"),(\"AocType\", \"AU\"));" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var premiumsAU_CDC = premiumsAU.ComputeDiscountAndCumulate( discountRates, amountTypes );" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "and on the Experience Variance step" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var premiumsEV = nominals.Filter((\"AmountType\", \"PR\"),(\"AocType\", \"EV\"));" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var premiumsEV_CDC = premiumsEV.ComputeDiscountAndCumulate( discountRates, amountTypes );" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Evaluating the Delta for a given step" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var premiums_Delta_EV_AU = (premiumsEV_CDC - premiumsAU_CDC).Aggregate();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "The contribution to the Present Value related to the Experience Variance AoC step, is given by the third element of the Values array, ", + "\nwhich corresponds to the value at the EOP of the current quarter, that is, the BOP of the next one" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "-premiums_Delta_EV_AU.Values[3]" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "This Delta Present Value can then be compared with the value provided in the [reporting table](#present-value-report). ", + "\n", + "\nNote that the minus sign is needed to reconcile with the reserve view of the reports. " + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "---" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/PresentValueSeries/PresentValue - Episode 3.ipynb b/PresentValueSeries/PresentValue - Episode 3.ipynb new file mode 100644 index 00000000..236312fb --- /dev/null +++ b/PresentValueSeries/PresentValue - Episode 3.ipynb @@ -0,0 +1,564 @@ +{ + "metadata": { + "authors": [], + "kernelspec": { + "display_name": "Formula Framework", + "language": "C#", + "name": "C#" + }, + "language_info": { + "file_extension": ".cs", + "mimetype": "text/plain", + "name": "C#" + }, + "toc-autonumbering": "True", + "toc-showcode": "False", + "toc-showmarkdowntxt": "False", + "toc-showtags": "False" + }, + "nbformat": 4, + "nbformat_minor": 5, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "

How to compute Present Values

" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "> IFRS 17 is a new accounting standard for insurance contracts. It is an economic accounting approach, replacing the nominal accounting of the previous standard IFRS 4, that is, the economic value of the insurance products is considered. The focus is on the liabilities of an insurance company, namely the insurance policies. ", + "\n", + "\n

" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "
", + "\n", + "\nThe aim of this notebook is to illustrate the IFRS 17 *Present Value* calculation using Systemorph Cloud Technology. Present Values are the amount of money that someone would pay in the present day for the contracts of the group up to their run off. The starting point are the so called *Nominal Cash flows*, which express the amounts of cash and cash equivalents being transferred into and out of a business. Cash flow values are **discounted** according to the *Yield Curve* provided as economic input in order to take into account the corresponding Interest Accretion, and the discounted figures are **cumulated** to find the **Present Values**. ", + "\n", + "\nThe IFRS 17 standard prescribes that the accounting statements are based on the value of a group of insurance contracts at the beginning of the period (BoP), their development throughout the period, and the value at the end of the period (EoP). While the period is typically a quarter, the **Analysis of Change** (AoC) from BoP to EoP per group of contract is made considering for each step the variation of the cashflow so as to enhance the readability of the value changes. To this aim it is necessary to **evaluate the Present Value difference** (or delta) between each step, yielding the figures shown in the resulting report.", + "\n", + "\nThis process is pictorially represented in the flowchart below" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "
" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "---", + "\n", + "\nImport the IFRS17 calculation engine:" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "#!import \"//ifrs17/v1.0.0/CalculationEngine\"" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Initialize basic pre-configured dimensions that can be tuned to reflect for your company and business. Example of such dimensions are", + "\n", + "\n**Reporting Nodes**: hierarchical structure of the company, where the root is the *Group* level and the end nodes are the levels at which data is imported.", + "\n", + "\n**Data Nodes**: Grouping of (Re-)Insurance Contracts belonging to the same Portfolio, and defined by their Reporting Node, Scenario, Contractual Currency, FunctionalCurrency, LineOfBusiness, ValuationApproach, and OCI Type. ", + "\n", + "\n**Aoc Type**: the Analysis of Change steps used for accounting statements." + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "#!eval-notebook \"InitializeData\"" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "---" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Import" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "In the following code cells, the necessary data to start the IFRS calculator are being imported.", + "\nAfter the standard dimensions and parameters are loaded, for the calculation of the Present Value ", + "\none needs the economic input yield curves for the target period", + "\nand the nominal cashflows for the desired group of contracts:", + "\n", + "\n**Yield Curve**: line that plots yields, i.e. interest rates. It depends on the given currency related to the target *Reporting Node*, and is imported on a yierly basis. The slope of the yield curve gives an idea of future interest rate changes and economic activity.", + "\n", + "\n**Nominal Cashflows**: they are the amounts of cash and cash equivalents that a company expects to transfer into and out of a business, without any adjustment. This is useful for anticipating future revenue and expenses.", + "\n", + "\nThe import process of these example spreadsheets can be completed by running the two cells below" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Import.FromFile(\"DataNodes_CH.xlsx\").WithFormat(\"DataNode\").WithTarget(DataSource).ExecuteAsync()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Import.FromFile(\"DataNodes_DE.xlsx\").WithFormat(\"DataNode\").WithTarget(DataSource).ExecuteAsync()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Import.FromFile(\"YieldCurve.xlsx\").WithType().WithTarget(DataSource).ExecuteAsync()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Import.FromFile(\"Cashflows.xlsx\").WithFormat(\"Cashflow\").WithTarget(DataSource).ExecuteAsync()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Import.FromFile(\"CF_CH_2021_12.xlsx\").WithFormat(\"Cashflow\").WithTarget(DataSource).ExecuteAsync()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Import.FromFile(\"CF_DE_2021_12.xlsx\").WithFormat(\"Cashflow\").WithTarget(DataSource).ExecuteAsync()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Import.FromFile(\"CF_DE_2022_12.xlsx\").WithFormat(\"Cashflow\").WithTarget(DataSource).ExecuteAsync()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "ifrs17.Reset(Workspace)" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "



", + "\n", + "\n", + "\n# Present Value Report" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Present Value is today’s value of money you expect from future income and is calculated as the sum of future investment returns discounted at a specified level of rate of return expectation.", + "\n", + "\nThe change of the Present Value in the target period is analysed following the Analysis of Change method." + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var pv = ifrs17.PresentValues;" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "pv.ReportingNode = \"DE\";", + "\npv.ReportingPeriod = (2022, 12);", + "\npv.ColumnSlices = new[] {\"ReportingNode\", \"EstimateType\", \"AmountType\"};", + "\npv.DataFilter = new[] {(\"EconomicBasis\", \"L\")};" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await pv.ToReportAsync" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "














", + "\n", + "\n# View imported Data" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Systemorph notebook technology excels in analyse on the fly the imported data. In this section the newly imported Yield Curves and nominal cashflows can be analysed." + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "**Imported Yield Curve**" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var yieldCurves = await DataSource.Query().ToArrayAsync();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Report.ForDataCube(yieldCurves.ToReportType()).SliceRowsBy(\"Currency\").SliceColumnsBy(\"Index\").ToLineChart().ExecuteAsync() with { Width = 1000 }" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "**Imported Nominal Cashflows**" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await DataSource.Partition.SetAsync( new {ReportingNode = pv.ReportingNode, Year = pv.ReportingPeriod.Year, Month = pv.ReportingPeriod.Month, Scenario = (string)null} );" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var nominals = (await DataSource.Query().ToArrayAsync()).ToDataCube();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await Report.ForDataCube(nominals.ToReportType()).SliceRowsBy(\"AmountType\",\"AocType\").SliceColumnsBy(\"Index\").WithQuerySource(Workspace).ToBarChart().ExecuteAsync()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Discounting and Cumulate" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "The list of **Amount Types** are retrieved from the Data Source" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var amountTypes = await DataSource.Query().ToArrayAsync();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "The **Yield Curve** associated to the target Group of Contract Reporting Node Currency is selected for the computation of the Discount rates", + "\n", + "\n$$", + "\n\\text{Discount}_i = \\big( 1 + \\text{YieldCurve}_i \\big) ^{-\\frac{1}{12}} ~.", + "\n$$" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var discountRates = ( from yc in yieldCurves.FirstOrDefault(x => x.Currency == \"CHF\").Values select Math.Pow((1 + yc),( - 1.0 / 12.0 )) ).ToArray();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Before discounting the cash flows, it is necessary to match the discount rates starting period with the target period selected in the [report](#present-value-report). ", + "\nSince the imported Yearly Yield Curve starts from the year 2021, we can simply skip the past elements with the aid of the following cell " + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "discountRates = discountRates.Skip(pv.ReportingPeriod.Year - 2021).ToArray();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "The Cumulated Discounted Cashflow ($\\text{CDC}$) is defined by the following recursive formulas", + "\n", + "\n$$", + "\n\\text{CDC}_t = \\left\\{", + "\n\\begin{array}{cl}", + "\n\\text{Nominal}_t + \\text{CDC}_{t+1} \\cdot {\\text{Valid Discount}_{\\frac{t}{12}}} ~, & \\text{if Period Type is Beginning of Period} \\\\", + "\n\\big( \\text{Nominal}_t + \\text{CDC}_{t+1} \\big) \\cdot {\\text{Valid Discount}_{\\frac{t}{12}}} ~, & \\text{if Period Type is End of Period}", + "\n\\end{array}", + "\n\\right.", + "\n$$", + "\n", + "\nwhere the Period Type depends on the given cashflow Amount Type. " + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "In the following, the premiums are retrieved from the nominals **Data Cube** through a simple Filter. ", + "\nAdditionally, among the list of premiums provided, we select only the cashflows for the Assumption Update (AU) and Experience Variance (EV) steps." + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "The discount and cumulation operation can be performed on the resulting Data Cube through the method ComputeDiscountAndCumulateAsync provided by the solution. We focus on the Assumption Update step" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var premiumsAU = nominals.Filter((\"AmountType\", \"PR\"),(\"AocType\", \"AU\"));" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var premiumsAU_CDC = premiumsAU.ComputeDiscountAndCumulate( discountRates, amountTypes );" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "and on the Experience Variance step" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var premiumsEV = nominals.Filter((\"AmountType\", \"PR\"),(\"AocType\", \"EV\"));" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var premiumsEV_CDC = premiumsEV.ComputeDiscountAndCumulate( discountRates, amountTypes );" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Evaluating the Delta for a given step" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var premiums_Delta_EV_AU = (premiumsEV_CDC - premiumsAU_CDC).Aggregate();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "The contribution to the Present Value related to the Experience Variance AoC step, is given by the n-th element of the Values array, ", + "\nwith $n$ equal to the target Month. This element corresponds to the value at the EOP of the current quarter, that is, the BOP of the next one" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "-premiums_Delta_EV_AU.Values[12]" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "This Delta Present Value can then be compared with the value provided in the [reporting table](#present-value-report). ", + "\n", + "\nNote that the minus sign is needed to reconcile with the reserve view of the reports. " + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "---" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/PresentValueSeries/Readme.md b/PresentValueSeries/Readme.md new file mode 100644 index 00000000..b6aa51d8 --- /dev/null +++ b/PresentValueSeries/Readme.md @@ -0,0 +1,161 @@ + + +
+ +Together with the present project, we produced a series consisting of **three episodes** tackling the following topics: + +
+ + + +Given that this project and video series is focused on Present Values and Analysis of Change approach, +the full IFRS 17 solution is much broader and provides a lot more functionalities than those presented +in this project. We invite you to clone the +[IFRS 17 Template](https://portal.systemorph.cloud/project/ifrs17-template) +in order to test the full end-to-end solution. +You can reuse the data you prepared for this project in the Full Template project as well. + +Additionally, if you are interested in the implemented methodologies and are keen to learn from +our open-source IFRS 17 code and documentation, please refer to the +[IFRS 17 Calculation Engine](https://portal.systemorph.cloud/project/ifrs17). + + +## The Theory Behind Economic Accounting + +The content of this section is presented in the first +[episode](https://youtu.be/cEEHJhZOCWI) +of this series. + +Computing the Present Value of the insurance contracts is the main goal of the IFRS 17 economic accounting standard. +Briefly, this is the fair price one would pay for all these insurance policies today. + +For computing Present Values, the insurance contracts are allocated to homogeneous groups usually formed by type, +line of business, annual cohort to simplify reporting without a distinct loss of accuracy. +The Present Value is computed for each group of insurance contracts individually. +This requires that all the cash flows are estimated and modelled until the product is run off. +These are the amounts of cash and cash equivalents being transferred into and out of a business, +such as premium incomes, benefits, claims, and expenses. +Due to the growth of the market and the inflation, the time of the expected cash flow impacts +the Present Value of that cash flow. +The timespan from now until the time of the cash flow is called maturity. + +

+ +Overview +

+ +The Present Value of a cash flow is computed as the discounted cash flow +and can be expressed through the following formula: + +
+ +$$ \text{PresentValue} = \displaystyle\frac{\text{CashFlow}}{(1+\text{InterestRate})^{\text{MaturityYears} }} ~.$$ + +
+ +The total Present Value of the policy is then the sum of Present Values of all cash flows. + +Every period (typically every quarter) an insurance company will need to prepare a statement of the Present Value of future cash flows. This statement is based on the value of a group of insurance contracts at the beginning of the period, its development throughout the period, and the value at the end of the period. Different effects contribute to the change in value between the beginning and the end of a period and these effects are shown in the Analysis of Change. + +

+ +WaterfallChart +

+ +In this analysis, we identify different components and their effects on the Present Value in the form of deltas, such as + - Model correction for existing business, + - Actual cash flows (which may differ from prior expectation), + - Interest accretion, where the interest on different amounts manifests itself over the period, + - Experience variance, new assessment by actuaries given newest developments, + - Assumption updates, e.g., a new mortality table, + - Financial assumption updates, e.g., a new yield curve, + - Combined liabilities, a final run combining in-force and new business. + + +## On the Calculation and Reporting + +The content of this section refers to the second [episode](https://youtu.be/dhdA3F6ZWbs). + +This episode aims at demonstrating the use of the IFRS 17 calculation engine for computing Present Values using the standard IFRS 17 Calculation Engine and the notebook **PresentValues - Episode 2**. Vanessa and Andrea will guide you through this journey. + +

+ +VanessaAndrea +

+ +The interest and discount rates can be derived by the assumed yield curve, which is stored in the file `YieldCurve.xlsx`, and imported in the notebook as the economic input. Conversely, the values of the modelled cash flows are stored in the file `Cashflows.xlsx` forming the insurance input. From both inputs and thanks to the methods provided by the Systemorph IFRS 17 Calculation Engine, it is possible to discount and comulate the cash flows, from which deltas can be computed and reported +per each step of the Analysis of Change. + +

+ +flowchart +

+ +In the last section of the notebook these steps are taken individually for a selected Analysis of Change Step, so that the calculation can be checked. + + +## How To Customize The Input: Do It Yourself + +The content of this section refers to the third +and last [episode](https://youtu.be/n7KO5-NKTng) of this series. + +Its aim is to present how to customize the setup described in the Episode 2 to your business data set and company. The corresponding notebook is named **PresentValues - Episode 3**. + +Firstly, the case of a company with many legal entities is covered, so that group of contracts can be defined for the (e.g.) Swiss and German reporting nodes separately. This use case is discussed with examples of dedicated cash flows imported for the two groups, together with the reports of the corresponding Present Values. so the corresponding Present Values can be reported. +Lastly, the episode describes how to add a custom Analysis of Change step to the list. This task can be achieved simply by adding the entry in the AocType tab of the `Dimensions.xlsx` file. Automatic configuration are applied to this step in order to allow users to start importing cash flows for this freshly created step effortlessly. + +
+ + +## Got Questions? + +For support around the **Full IFRS 17 Template** project get in contact with our +[Community Team](https://systemorph.cloud/community) or contact us through +[Linkedin](https://www.linkedin.com/company/systemorph) or add your questions directly on +[YouTube channel](https://www.youtube.com/@systemorph) videos. + + +## Contributing + +All work on the **Full IFRS 17 Template** happens directly on +[GitHub](https://github.com/Systemorph/IFRS17CalculationEngine). +From here, you can get to know about future releases, track the current work and report issues. + +
+ +
+ +This project adheres to our [General Terms & Conditions](https://systemorph.cloud/general-terms-and-conditions/). + +
+ + + + + + diff --git a/PresentValueSeries/YieldCurve.xlsx b/PresentValueSeries/YieldCurve.xlsx new file mode 100644 index 00000000..adf129f5 Binary files /dev/null and b/PresentValueSeries/YieldCurve.xlsx differ diff --git a/full-ifrs17-template/Report/Reports.ipynb b/full-ifrs17-template/Report/Reports.ipynb index e7e1391c..a6e15bad 100644 --- a/full-ifrs17-template/Report/Reports.ipynb +++ b/full-ifrs17-template/Report/Reports.ipynb @@ -69,9 +69,9 @@ "cell_type": "code", "source": [ "Workspace.InitializeFrom(DataSource);", - "\nifrs17Report.Reset(Workspace)" - ], - "metadata": {}, + "\nifrs17.Reset(Workspace)" + ] + "metadata": {}, "execution_count": 0, "outputs": [] }, @@ -94,17 +94,14 @@ { "cell_type": "code", "source": [ - "var pvReport = ifrs17Report.PresentValues;", - "\npvReport.ReportingNode = \"CH\";", - "\npvReport.ReportingPeriod = (2021, 3);", - "\npvReport.CurrencyType = CurrencyType.Contractual;", - "\npvReport.ColumnSlices = new string[]{};//\"GroupOfContract\", \"AmountType\"", - "\npvReport.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.2\"),(\"LiabilityType\", \"LIC\") }", - "\n(await pvReport.ToReportAsync) with {Height = 720}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] + "var pv = ifrs17.PresentValues;", + "\npv.ReportingNode = \"CH\";", + "\npv.ReportingPeriod = (2021, 3);", + "\npv.CurrencyType = CurrencyType.Contractual;", + "\npv.ColumnSlices = new string[]{};//\"GroupOfContract\", \"AmountType\"", + "\npv.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.2\"),(\"LiabilityType\", \"LIC\") }", + "\n(await pv.ToReportAsync) with {Height = 720}" + ] }, { "cell_type": "markdown", @@ -122,16 +119,13 @@ { "cell_type": "code", "source": [ - "var raReport = ifrs17Report.RiskAdjustments;", - "\nraReport.ReportingNode = \"CH\";", - "\nraReport.ReportingPeriod = (2021, 3);", - "\nraReport.ColumnSlices = new string[]{};//\"GroupOfContract\", \"EconomicBasis\"", - "\nraReport.DataFilter = null;//new [] {(\"GroupOfContract\", \"DT1.2\")};", - "\n(await raReport.ToReportAsync) with {Height = 800}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] + "var ra = ifrs17.RiskAdjustments;", + "\nra.ReportingNode = \"CH\";", + "\nra.ReportingPeriod = (2021, 3);", + "\nra.ColumnSlices = new string[]{};//\"GroupOfContract\", \"EconomicBasis\"", + "\nra.DataFilter = null;//new [] {(\"GroupOfContract\", \"DT1.2\")};", + "\n(await ra.ToReportAsync) with {Height = 800}" + ] }, { "cell_type": "markdown", @@ -150,16 +144,13 @@ { "cell_type": "code", "source": [ - "var writtenActualReport = ifrs17Report.WrittenActuals;", - "\nwrittenActualReport.ReportingNode = \"CH\";", - "\nwrittenActualReport.ReportingPeriod = (2021, 3);", - "\nwrittenActualReport.ColumnSlices = new string[]{};//\"GroupOfContract\"", - "\nwrittenActualReport.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", - "\n(await writtenActualReport.ToReportAsync) with {Height = 400}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] + "var writtenActual = ifrs17.WrittenActuals;", + "\nwrittenActual.ReportingNode = \"CH\";", + "\nwrittenActual.ReportingPeriod = (2021, 3);", + "\nwrittenActual.ColumnSlices = new string[]{};//\"GroupOfContract\"", + "\nwrittenActual.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", + "\n(await writtenActual.ToReportAsync) with {Height = 400}" + ] }, { "cell_type": "markdown", @@ -178,16 +169,13 @@ { "cell_type": "code", "source": [ - "var accrualActualReport = ifrs17Report.AccrualActuals;", - "\naccrualActualReport.ReportingNode = \"CH\";", - "\naccrualActualReport.ReportingPeriod = (2021, 3);", - "\naccrualActualReport.ColumnSlices = new string[]{};//\"GroupOfContract\", \"AmountType\"", - "\naccrualActualReport.DataFilter = null; //new [] {(\"EstimateType\", \"AA\")};", - "\n(await accrualActualReport.ToReportAsync) with {Height = 400}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] + "var accrualActual = ifrs17.AccrualActuals;", + "\naccrualActual.ReportingNode = \"CH\";", + "\naccrualActual.ReportingPeriod = (2021, 3);", + "\naccrualActual.ColumnSlices = new string[]{};//\"GroupOfContract\", \"AmountType\"", + "\naccrualActual.DataFilter = null; //new [] {(\"EstimateType\", \"AA\")};", + "\n(await accrualActual.ToReportAsync) with {Height = 400}" + ] }, { "cell_type": "markdown", @@ -203,16 +191,13 @@ { "cell_type": "code", "source": [ - "var deferrableActualReport = ifrs17Report.DeferralActuals;", - "\ndeferrableActualReport.ReportingNode = \"CH\";", - "\ndeferrableActualReport.ReportingPeriod = (2021, 3);", - "\ndeferrableActualReport.ColumnSlices = new string[]{};//\"GroupOfContract\", \"AmountType\"", - "\ndeferrableActualReport.DataFilter = null;//new [] {(\"GroupOfContract\", \"DT1.1\")};", - "\n(await deferrableActualReport.ToReportAsync) with {Height = 400}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] + "var deferrableActual = ifrs17.DeferralActuals;", + "\ndeferrableActual.ReportingNode = \"CH\";", + "\ndeferrableActual.ReportingPeriod = (2021, 3);", + "\ndeferrableActual.ColumnSlices = new string[]{};//\"GroupOfContract\", \"AmountType\"", + "\ndeferrableActual.DataFilter = null;//new [] {(\"GroupOfContract\", \"DT1.1\")};", + "\n(await deferrableActual.ToReportAsync) with {Height = 400}" + ] }, { "cell_type": "markdown", @@ -232,16 +217,13 @@ { "cell_type": "code", "source": [ - "var fulfillmentCashflowsReport = ifrs17Report.FulfillmentCashflows;", - "\nfulfillmentCashflowsReport.ReportingNode = \"CH\";", - "\nfulfillmentCashflowsReport.ReportingPeriod = (2021, 3);", - "\nfulfillmentCashflowsReport.ColumnSlices = new string[]{};//\"EstimateType\"", - "\nfulfillmentCashflowsReport.DataFilter = null;// new [] {(\"GroupOfContract\", \"DT1.1\")};", - "\n(await fulfillmentCashflowsReport.ToReportAsync) with {Height = 750}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] + "var fulfillmentCashflows = ifrs17.FulfillmentCashflows;", + "\nfulfillmentCashflows.ReportingNode = \"CH\";", + "\nfulfillmentCashflows.ReportingPeriod = (2021, 3);", + "\nfulfillmentCashflows.ColumnSlices = new string[]{};//\"EstimateType\"", + "\nfulfillmentCashflows.DataFilter = null;// new [] {(\"GroupOfContract\", \"DT1.1\")};", + "\n(await fulfillmentCashflows.ToReportAsync) with {Height = 750}" + ] }, { "cell_type": "markdown", @@ -257,16 +239,13 @@ { "cell_type": "code", "source": [ - "var experienceAdjustmentsReport = ifrs17Report.ExperienceAdjustments;", - "\nexperienceAdjustmentsReport.ReportingNode = \"CH\";", - "\nexperienceAdjustmentsReport.ReportingPeriod = (2021, 3);", - "\nexperienceAdjustmentsReport.ColumnSlices = new string[]{};//\"GroupOfContract\", \"AmountType\"", - "\nexperienceAdjustmentsReport.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", - "\n(await experienceAdjustmentsReport.ToReportAsync) with {Height = 300}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] + "var experienceAdjustments = ifrs17.ExperienceAdjustments;", + "\nexperienceAdjustments.ReportingNode = \"CH\";", + "\nexperienceAdjustments.ReportingPeriod = (2021, 3);", + "\nexperienceAdjustments.ColumnSlices = new string[]{};//\"GroupOfContract\", \"AmountType\"", + "\nexperienceAdjustments.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", + "\n(await experienceAdjustments.ToReportAsync) with {Height = 300}" + ] }, { "cell_type": "markdown", @@ -283,16 +262,13 @@ { "cell_type": "code", "source": [ - "var technicalMarginsReport = ifrs17Report.TechnicalMargins;", - "\ntechnicalMarginsReport.ReportingNode = \"CH\";", - "\ntechnicalMarginsReport.ReportingPeriod = (2021, 3);", - "\ntechnicalMarginsReport.ColumnSlices = new string[]{};//\"GroupOfContract\", \"AmountType\"", - "\ntechnicalMarginsReport.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", - "\n(await technicalMarginsReport.ToReportAsync) with {Height = 600}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] + "var technicalMargins = ifrs17.TechnicalMargins;", + "\ntechnicalMargins.ReportingNode = \"CH\";", + "\ntechnicalMargins.ReportingPeriod = (2021, 3);", + "\ntechnicalMargins.ColumnSlices = new string[]{};//\"GroupOfContract\", \"AmountType\"", + "\ntechnicalMargins.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", + "\n(await technicalMargins.ToReportAsync) with {Height = 600}" + ] }, { "cell_type": "markdown", @@ -310,16 +286,13 @@ { "cell_type": "code", "source": [ - "var allocatedTechnicalMarginsReport = ifrs17Report.AllocatedTechnicalMargins;", - "\nallocatedTechnicalMarginsReport.ReportingNode = \"CH\";", - "\nallocatedTechnicalMarginsReport.ReportingPeriod = (2021, 3);", - "\nallocatedTechnicalMarginsReport.ColumnSlices = new string[]{\"GroupOfContract\", \"EstimateType\"};//\"GroupOfContract\", \"AmountType\"", - "\nallocatedTechnicalMarginsReport.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", - "\n(await allocatedTechnicalMarginsReport.ToReportAsync) with {Height = 700}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] + "var allocatedTechnicalMargins = ifrs17.AllocatedTechnicalMargins;", + "\nallocatedTechnicalMargins.ReportingNode = \"CH\";", + "\nallocatedTechnicalMargins.ReportingPeriod = (2021, 3);", + "\nallocatedTechnicalMargins.ColumnSlices = new string[]{\"GroupOfContract\", \"EstimateType\"};//\"GroupOfContract\", \"AmountType\"", + "\nallocatedTechnicalMargins.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", + "\n(await allocatedTechnicalMargins.ToReportAsync) with {Height = 700}" + ] }, { "cell_type": "markdown", @@ -335,16 +308,13 @@ { "cell_type": "code", "source": [ - "var actuarialLrcReport = ifrs17Report.ActuarialLrc;", - "\nactuarialLrcReport.ReportingNode = \"CH\";", - "\nactuarialLrcReport.ReportingPeriod = (2021, 3);", - "\nactuarialLrcReport.ColumnSlices = new string[]{};//\"GroupOfContract\"", - "\nactuarialLrcReport.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", - "\n(await actuarialLrcReport.ToReportAsync) with {Height = 750}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] + "var actuarialLrc = ifrs17.ActuarialLrc;", + "\nactuarialLrc.ReportingNode = \"CH\";", + "\nactuarialLrc.ReportingPeriod = (2021, 3);", + "\nactuarialLrc.ColumnSlices = new string[]{};//\"GroupOfContract\"", + "\nactuarialLrc.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", + "\n(await actuarialLrc.ToReportAsync) with {Height = 750}" + ] }, { "cell_type": "markdown", @@ -360,16 +330,13 @@ { "cell_type": "code", "source": [ - "var lrcReport = ifrs17Report.Lrc;", - "\nlrcReport.ReportingNode = \"CH\";", - "\nlrcReport.ReportingPeriod = (2021, 3);", - "\nlrcReport.ColumnSlices = new string[]{};//\"GroupOfContract\",", - "\nlrcReport.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", - "\n(await lrcReport.ToReportAsync) with {Height = 250}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] + "var lrc = ifrs17.Lrc;", + "\nlrc.ReportingNode = \"CH\";", + "\nlrc.ReportingPeriod = (2021, 3);", + "\nlrc.ColumnSlices = new string[]{};//\"GroupOfContract\",", + "\nlrc.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", + "\n(await lrc.ToReportAsync) with {Height = 250}" + ] }, { "cell_type": "markdown", @@ -385,16 +352,13 @@ { "cell_type": "code", "source": [ - "var actuarialLicReport = ifrs17Report.ActuarialLic;", - "\nactuarialLicReport.ReportingNode = \"CH\";", - "\nactuarialLicReport.ReportingPeriod = (2021, 3);", - "\nactuarialLicReport.ColumnSlices = new string[]{};//\"GroupOfContract\", \"AmountType\"", - "\nactuarialLicReport.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", - "\n(await actuarialLicReport.ToReportAsync) with {Height = 750}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] + "var actuarialLic = ifrs17.ActuarialLic;", + "\nactuarialLic.ReportingNode = \"CH\";", + "\nactuarialLic.ReportingPeriod = (2021, 3);", + "\nactuarialLic.ColumnSlices = new string[]{};//\"GroupOfContract\", \"AmountType\"", + "\nactuarialLic.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", + "\n(await actuarialLic.ToReportAsync) with {Height = 750}" + ] }, { "cell_type": "markdown", @@ -410,16 +374,13 @@ { "cell_type": "code", "source": [ - "var licReport = ifrs17Report.Lic;", - "\nlicReport.ReportingNode = \"CH\";", - "\nlicReport.ReportingPeriod = (2021, 3);", - "\nlicReport.ColumnSlices = new string[]{};//\"GroupOfContract\", \"AmountType\"", - "\nlicReport.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", - "\n(await licReport.ToReportAsync) with {Height = 250}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] + "var lic = ifrs17.Lic;", + "\nlic.ReportingNode = \"CH\";", + "\nlic.ReportingPeriod = (2021, 3);", + "\nlic.ColumnSlices = new string[]{};//\"GroupOfContract\", \"AmountType\"", + "\nlic.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", + "\n(await lic.ToReportAsync) with {Height = 250}" + ] }, { "cell_type": "markdown", @@ -437,16 +398,13 @@ { "cell_type": "code", "source": [ - "var financialPerformanceReport = ifrs17Report.FinancialPerformance;", - "\nfinancialPerformanceReport.ReportingNode = \"CH\";", - "\nfinancialPerformanceReport.ReportingPeriod = (2021, 3);", - "\nfinancialPerformanceReport.ColumnSlices = new string[]{};//\"GroupOfContract\"", - "\nfinancialPerformanceReport.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", - "\n(await financialPerformanceReport.ToReportAsync) with { Height = 900, GroupDefaultExpanded = 3}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] + "var financialPerformance = ifrs17.FinancialPerformance;", + "\nfinancialPerformance.ReportingNode = \"CH\";", + "\nfinancialPerformance.ReportingPeriod = (2021, 3);", + "\nfinancialPerformance.ColumnSlices = new string[]{};//\"GroupOfContract\"", + "\nfinancialPerformance.DataFilter = null; //new [] {(\"GroupOfContract\", \"DT1.1\")};", + "\n(await financialPerformance.ToReportAsync) with { Height = 900, GroupDefaultExpanded = 3}" + ] }, { "cell_type": "code", @@ -458,4 +416,4 @@ "outputs": [] } ] -} \ No newline at end of file +} diff --git a/ifrs17/CalculationEngine.ipynb b/ifrs17/CalculationEngine.ipynb index 1fa93770..288ee9fb 100644 --- a/ifrs17/CalculationEngine.ipynb +++ b/ifrs17/CalculationEngine.ipynb @@ -31,7 +31,7 @@ { "cell_type": "code", "source": [ - "var ifrs17Report = new Ifrs17Reports(Workspace, Scopes, Report);" + "var ifrs17 = new Ifrs17(Workspace, Scopes, Report);" ], "metadata": {}, "execution_count": 0, diff --git a/ifrs17/DataModel/DataStructure.ipynb b/ifrs17/DataModel/DataStructure.ipynb index f18052af..0b0d6fcb 100644 --- a/ifrs17/DataModel/DataStructure.ipynb +++ b/ifrs17/DataModel/DataStructure.ipynb @@ -65,7 +65,8 @@ "\n#r \"nuget:Systemorph.DataSetReader,1.5.2\"", "\n#r \"nuget:Systemorph.DataSource,1.5.4\"", "\n#r \"nuget:Systemorph.DataSource.Conversions,1.5.4\"", - "\n#r \"nuget:Systemorph.Reporting,1.5.7\"" + "\n#r \"nuget:Systemorph.Reporting,1.5.7\"", + "\n#r \"nuget:Systemorph.Charting,1.5.7\"" ], "metadata": {}, "execution_count": 0, diff --git a/ifrs17/Import/Importers.ipynb b/ifrs17/Import/Importers.ipynb index 848abb61..a1c956c0 100644 --- a/ifrs17/Import/Importers.ipynb +++ b/ifrs17/Import/Importers.ipynb @@ -119,7 +119,10 @@ "\n await workspace.DeleteAsync( await workspace.Query().ToArrayAsync() );", "\n }", "\n ", - "\n ReportingNode = (await dataSource.Query().Where(x => x.SystemName == args.ReportingNode).ToArrayAsync()).First();", + "\n var reportingNodes = (await dataSource.Query().Where(x => x.SystemName == args.ReportingNode).ToArrayAsync());", + "\n if(!reportingNodes.Any()) { ApplicationMessage.Log(Error.ReportingNodeNotFound, args.ReportingNode); return; }", + "\n ReportingNode = reportingNodes.First();", + "\n", "\n var aocConfigurationByAocStep = await dataSource.LoadAocStepConfigurationAsync(args.Year, args.Month);", "\n AocTypeMap = args.ImportFormat switch {", "\n ImportFormats.Cashflow => aocConfigurationByAocStep.Where(x => x.InputSource.Contains(InputSource.Cashflow) &&", @@ -258,7 +261,7 @@ { "cell_type": "code", "source": [ - "async public Task CleanDatabaseFromPartitionAsync (Guid partitionId, Func filter = null) where T : class, IPartitioned", + "public async Task CleanDatabaseFromPartitionAsync (Guid partitionId, Func filter = null) where T : class, IPartitioned", "\n{", "\n var loadData = (await DataSource.Query().Where(x => x.Partition == partitionId).ToArrayAsync())", "\n .Where(filter?? (Func)(x => true)).ToList();", @@ -281,10 +284,10 @@ { "cell_type": "code", "source": [ - "async public Task CommitToDatabase (Guid partitionId, bool snapshot = true, Func filter = null) where T : class, IPartitioned", + "public async Task CommitToDatabase (IWorkspace workspace, Guid partitionId, bool snapshot = true, Func filter = null) where T : class, IPartitioned", "\n{", "\n if(snapshot) await CleanDatabaseFromPartitionAsync(partitionId, filter);", - "\n await DataSource.UpdateAsync( await Workspace.Query().ToArrayAsync() );", + "\n await DataSource.UpdateAsync( await workspace.Query().ToArrayAsync() );", "\n await DataSource.CommitAsync();", "\n}" ], @@ -552,10 +555,10 @@ { "cell_type": "code", "source": [ - "public async Task UploadDataNodesToWorkspaceAsync(IDataSet dataSet)", + "public async Task UploadDataNodesToWorkspaceAsync(IDataSet dataSet, IWorkspace workspace)", "\n{", - "\n Workspace.Reset(x => x.ResetInitializationRules().ResetCurrentPartitions());", - "\n Workspace.Initialize(x => x.FromSource(DataSource)", + "\n workspace.Reset(x => x.ResetInitializationRules().ResetCurrentPartitions());", + "\n workspace.Initialize(x => x.FromSource(DataSource)", "\n .DisableInitialization()", "\n .DisableInitialization()", "\n .DisableInitialization()", @@ -565,7 +568,7 @@ "\n var args = await GetArgsFromMainAsync(dataSet);", "\n if(Activity.HasErrors()) return Activity.Finish();", "\n ", - "\n var storage = new ParsingStorage(args, DataSource, Workspace);", + "\n var storage = new ParsingStorage(args, DataSource, workspace);", "\n await storage.InitializeAsync();", "\n if(Activity.HasErrors()) return Activity.Finish();", "\n ", @@ -591,10 +594,10 @@ "\n ValuationApproach = datarow.Field(nameof(DataNode.ValuationApproach)),", "\n OciType = datarow.Field(nameof(DataNode.OciType))", "\n })", - "\n .WithTarget(Workspace)", + "\n .WithTarget(workspace)", "\n .ExecuteAsync();", "\n ", - "\n var portfolios = await Workspace.Query().ToDictionaryAsync(x => x.SystemName);", + "\n var portfolios = await workspace.Query().ToDictionaryAsync(x => x.SystemName);", "\n var importLogGroupOfContracts = await Import.FromDataSet(dataSet)", "\n .WithType((dataset, datarow) => {", "\n var gicSystemName = datarow.Field(nameof(DataNode.SystemName));", @@ -645,7 +648,7 @@ "\n };", "\n return ExtendGroupOfContract(gric, datarow);", "\n })", - "\n .WithTarget(Workspace)", + "\n .WithTarget(workspace)", "\n .ExecuteAsync();", "\n ", "\n return Activity.Finish().Merge(importLogPortfolios).Merge(importLogGroupOfContracts);", @@ -659,12 +662,13 @@ "cell_type": "code", "source": [ "Import.DefineFormat(ImportFormats.DataNode, async (options, dataSet) => {", - "\n var log = await UploadDataNodesToWorkspaceAsync(dataSet);", - "\n var partition = (Guid)Workspace.Partition.GetCurrent(nameof(PartitionByReportingNode));", - "\n await CommitToDatabase(partition);", - "\n await CommitToDatabase(partition);", - "\n await CommitToDatabase(partition);", - "\n await CommitToDatabase(partition);", + "\n var workspace = Workspace.CreateNew();", + "\n var log = await UploadDataNodesToWorkspaceAsync(dataSet, workspace);", + "\n var partition = (Guid)workspace.Partition.GetCurrent(nameof(PartitionByReportingNode));", + "\n await CommitToDatabase(workspace, partition);", + "\n await CommitToDatabase(workspace, partition);", + "\n await CommitToDatabase(workspace, partition);", + "\n await CommitToDatabase(workspace, partition);", "\n return log;", "\n});" ], @@ -749,7 +753,7 @@ "source": [ "Import.DefineFormat(ImportFormats.DataNodeState, async (options, dataSet) => {", "\n var log = await UploadDataNodeStateToWorkspaceAsync(dataSet);", - "\n await CommitToDatabase((Guid)Workspace.Partition.GetCurrent(nameof(PartitionByReportingNode)), snapshot: false); ", + "\n await CommitToDatabase(Workspace, (Guid)Workspace.Partition.GetCurrent(nameof(PartitionByReportingNode)), snapshot: false); ", "\n return log;", "\n});" ], @@ -864,8 +868,8 @@ "\n Guid partitionId = new Guid();", "\n var log = await UploadDataNodeParameterToWorkspaceAsync(dataSet, partitionId);", "\n ", - "\n await CommitToDatabase(partitionId, snapshot: false);", - "\n await CommitToDatabase(partitionId, snapshot: false); ", + "\n await CommitToDatabase(Workspace, partitionId, snapshot: false);", + "\n await CommitToDatabase(Workspace, partitionId, snapshot: false); ", "\n ", "\n return log;", "\n});" @@ -902,9 +906,9 @@ { "cell_type": "code", "source": [ - "public async Task ValidateForDataNodeStateActiveAsync(Dictionary dataNodes) where T : BaseDataRecord", - "\n{ ", - "\n foreach(var item in (await Workspace.Query().ToArrayAsync()).GroupBy(x => x.DataNode))", + "public async Task ValidateForDataNodeStateActiveAsync(IWorkspace workspace, Dictionary dataNodes) where T : BaseDataRecord", + "\n{", + "\n foreach(var item in (await workspace.Query().ToArrayAsync()).GroupBy(x => x.DataNode))", "\n if(!dataNodes.ContainsKey(item.First().DataNode))", "\n ApplicationMessage.Log(Error.InactiveDataNodeState, item.First().DataNode);", "\n}" @@ -925,15 +929,13 @@ { "cell_type": "code", "source": [ - "public async Task ParseCashflowsToWorkspaceAsync(IDataSet dataSet, ImportArgs args)", + "public async Task ParseCashflowsToWorkspaceAsync(IDataSet dataSet, ImportArgs args, IWorkspace workspace)", "\n{", - "\n Workspace.Reset(x => x.ResetInitializationRules().ResetCurrentPartitions());", - "\n Workspace.Initialize(x => x.FromSource(DataSource)", - "\n .DisableInitialization()", - "\n .DisableInitialization());", + "\n workspace.Reset(x => x.ResetInitializationRules().ResetCurrentPartitions());", + "\n workspace.Initialize(x => x.FromSource(DataSource).DisableInitialization().DisableInitialization());", "\n ", "\n Activity.Start();", - "\n var parsingStorage = new ParsingStorage(args, DataSource, Workspace);", + "\n var parsingStorage = new ParsingStorage(args, DataSource, workspace);", "\n await parsingStorage.InitializeAsync();", "\n if(Activity.HasErrors()) return Activity.Finish();", "\n ", @@ -977,15 +979,16 @@ "\n Novelty = novelty,", "\n AmountType = amountType,", "\n EstimateType = estimateType,", - "\n AccidentYear = Int32.TryParse((datarow.Field(nameof(RawVariable.AccidentYear))), out var tempVal)? tempVal : (int?)null,", + "\n AccidentYear = dataset.Tables[ImportFormats.Cashflow].Columns.Where(x => x.ColumnName == nameof(RawVariable.AccidentYear)).Count()>0?", + "\n (Int32.TryParse((datarow.Field(nameof(RawVariable.AccidentYear))), out var accidentYear)? accidentYear : (int?)null) : (int?)null, ", "\n Partition = parsingStorage.TargetPartitionByReportingNodeAndPeriod.Id,", "\n Values = Multiply(GetSign((aocType, amountType, estimateType, dataNodeData.IsReinsurance), parsingStorage.HierarchyCache), values)", "\n };", "\n return item;", "\n }, ImportFormats.Cashflow", - "\n ).WithTarget(Workspace).ExecuteAsync();", + "\n ).WithTarget(workspace).ExecuteAsync();", "\n ", - "\n await ValidateForDataNodeStateActiveAsync(parsingStorage.DataNodeDataBySystemName);", + "\n await ValidateForDataNodeStateActiveAsync(workspace, parsingStorage.DataNodeDataBySystemName);", "\n return Activity.Finish().Merge(importLog);", "\n}" ], @@ -1002,10 +1005,11 @@ "\n await DataNodeFactoryAsync(dataSet, ImportFormats.Cashflow, args);", "\n if(Activity.HasErrors()) return Activity.Finish();", "\n ", - "\n var parsingLog = await ParseCashflowsToWorkspaceAsync(dataSet, args);", + "\n var workspace = Workspace.CreateNew();", + "\n var parsingLog = await ParseCashflowsToWorkspaceAsync(dataSet, args, workspace);", "\n if(parsingLog.Errors.Any()) return Activity.Finish().Merge(parsingLog);", "\n ", - "\n var storage = new ImportStorage(args, DataSource, Workspace);", + "\n var storage = new ImportStorage(args, DataSource, workspace);", "\n await storage.InitializeAsync();", "\n if(Activity.HasErrors()) return Activity.Finish().Merge(parsingLog);", "\n ", @@ -1014,12 +1018,14 @@ "\n var ivs = universe.GetScopes(identities).SelectMany(x => x.CalculatedIfrsVariables);", "\n if(Activity.HasErrors()) return Activity.Finish().Merge(parsingLog);", "\n ", - "\n await Workspace.UpdateAsync(ivs);", - "\n await CommitToDatabase(storage.TargetPartition, ", + "\n await workspace.UpdateAsync(ivs);", + "\n await CommitToDatabase(workspace,", + "\n storage.TargetPartition, ", "\n snapshot : true, ", "\n filter : x => storage.EstimateTypesByImportFormat[ImportFormats.Cashflow].Contains(x.EstimateType) && ", - "\n storage.DataNodesByImportScope[ImportScope.Primary].Contains(x.DataNode)); ", - "\n await CommitToDatabase(storage.TargetPartition, ", + "\n storage.DataNodesByImportScope[ImportScope.Primary].Contains(x.DataNode));", + "\n await CommitToDatabase(workspace, ", + "\n storage.TargetPartition, ", "\n snapshot : true,", "\n filter : x => storage.DataNodesByImportScope[ImportScope.Primary].Contains(x.DataNode));", "\n", @@ -1096,7 +1102,7 @@ "\n }, ImportFormats.Actual", "\n ).WithTarget(Workspace).ExecuteAsync();", "\n ", - "\n await ValidateForDataNodeStateActiveAsync(parsingStorage.DataNodeDataBySystemName);", + "\n await ValidateForDataNodeStateActiveAsync(Workspace, parsingStorage.DataNodeDataBySystemName);", "\n return Activity.Finish().Merge(importLog);", "\n}" ], @@ -1126,7 +1132,8 @@ "\n if(Activity.HasErrors()) return Activity.Finish().Merge(parsingLog);", "\n", "\n await Workspace.UpdateAsync(ivs);", - "\n await CommitToDatabase(storage.TargetPartition, ", + "\n await CommitToDatabase(Workspace, ", + "\n storage.TargetPartition, ", "\n snapshot : true, ", "\n filter : x => storage.EstimateTypesByImportFormat[ImportFormats.Actual].Contains(x.EstimateType) && ", "\n storage.DataNodesByImportScope[ImportScope.Primary].Contains(x.DataNode));", @@ -1219,7 +1226,7 @@ "\n foreach (var iv in invalidVariables)", "\n ApplicationMessage.Log(Error.MultipleTechnicalMarginOpening, $\"{iv.DataNode},{iv.AocType},{iv.Novelty}\");", "\n ", - "\n await ValidateForDataNodeStateActiveAsync(parsingStorage.DataNodeDataBySystemName);", + "\n await ValidateForDataNodeStateActiveAsync(Workspace, parsingStorage.DataNodeDataBySystemName);", "\n targetPartitionByReportingNodeAndPeriodId = parsingStorage.TargetPartitionByReportingNodeAndPeriod.Id;", "\n return Activity.Finish().Merge(importLog);", "\n}" @@ -1252,7 +1259,8 @@ "\n ", "\n Workspace.Query().Select(v => new {v.DataNode, v.AccidentYear}).Distinct();", "\n ", - "\n await CommitToDatabase(partitionId, ", + "\n await CommitToDatabase(Workspace, ", + "\n partitionId, ", "\n snapshot : true,", "\n filter : x => Workspace.Query().Select(v => v.DataNode).Distinct().Contains(x.DataNode));", "\n ", @@ -1295,7 +1303,8 @@ "\n if(Activity.HasErrors()) return Activity.Finish().Merge(parsingLog);", "\n", "\n await Workspace.UpdateAsync(ivs);", - "\n await CommitToDatabase(storage.TargetPartition, ", + "\n await CommitToDatabase(Workspace, ", + "\n storage.TargetPartition, ", "\n snapshot : true,", "\n filter : x => storage.EstimateTypesByImportFormat[ImportFormats.Opening].Contains(x.EstimateType) && ", "\n storage.DataNodesByImportScope[ImportScope.Primary].Contains(x.DataNode ));", diff --git a/ifrs17/Report/ReportConfigurationAndUtils.ipynb b/ifrs17/Report/ReportConfigurationAndUtils.ipynb index 355fb97c..df641ba1 100644 --- a/ifrs17/Report/ReportConfigurationAndUtils.ipynb +++ b/ifrs17/Report/ReportConfigurationAndUtils.ipynb @@ -182,6 +182,111 @@ "execution_count": 0, "outputs": [] }, + { + "cell_type": "markdown", + "source": [ + "# Utils" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Report Types" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "public record YieldCurveReport : KeyedRecord, IWithYearMonthAndScenario", + "\n{", + "\n [NotVisible] [Dimension(typeof(Currency))]", + "\n public string Currency { get; init; }", + "\n", + "\n [NotVisible] [Dimension(typeof(int), nameof(Year))]", + "\n public int Year { get; init; }", + "\n ", + "\n [NotVisible] [Dimension(typeof(int), nameof(Month))]", + "\n public int Month { get; init; }", + "\n", + "\n [NotVisible] [Dimension(typeof(Scenario))]", + "\n public string Scenario { get; init; }", + "\n", + "\n [NotVisible] [Dimension(typeof(int), nameof(Index))]", + "\n public int Index { get; init; }", + "\n", + "\n public double Value { get; init; }", + "\n}" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "public record RawVariableReport", + "\n{", + "\n [NotVisible] [Dimension(typeof(GroupOfContract))]", + "\n public string DataNode { get; init; }", + "\n ", + "\n [NotVisible] [AggregateBy] [Dimension(typeof(AocType))]", + "\n public string AocType { get; init; }", + "\n ", + "\n [NotVisible] [Dimension(typeof(Novelty))]", + "\n public string Novelty { get; init; }", + "\n", + "\n [NotVisible] [AggregateBy] [Dimension(typeof(AmountType))]", + "\n public string AmountType { get; init; }", + "\n", + "\n [NotVisible] [Dimension(typeof(EstimateType))]", + "\n public string EstimateType { get; init; }", + "\n", + "\n [NotVisible] [Dimension(typeof(int), nameof(Index))]", + "\n public int Index { get; init; }", + "\n", + "\n public double Value { get; init; }", + "\n}" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Converter Methods" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "public static IDataCube ToReportType (this YieldCurve[] yieldCurves)", + "\n => yieldCurves.SelectMany(yc => yc.Values.Select((x,i) => new YieldCurveReport { Currency = yc.Currency, Year = yc.Year, Month = yc.Month, Scenario = yc.Scenario, Index = i, Value = x })).ToDataCube();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "public static IDataCube ToReportType (this IDataCube rawVariable)", + "\n => rawVariable.SelectMany(rv => rv.Values.Select((x,i) => new RawVariableReport {", + "\n EstimateType = rv.EstimateType, AmountType = rv.AmountType, DataNode = rv.DataNode, AocType = rv.AocType, Novelty = rv.Novelty, Index = i, Value = x })).ToDataCube();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, { "cell_type": "code", "source": [ diff --git a/ifrs17/Report/ReportMutableScopes.ipynb b/ifrs17/Report/ReportMutableScopes.ipynb index 24b46333..358bbe69 100644 --- a/ifrs17/Report/ReportMutableScopes.ipynb +++ b/ifrs17/Report/ReportMutableScopes.ipynb @@ -306,7 +306,7 @@ { "cell_type": "code", "source": [ - "public class Ifrs17Reports ", + "public class Ifrs17 ", "\n{", "\n private Systemorph.Vertex.Scopes.Proxy.IScopeFactory scopes;", "\n private Systemorph.Vertex.Pivot.Builder.Interfaces.IPivotFactory report;", @@ -317,7 +317,7 @@ "\n public void Reset(IWorkspace workspace) => Storage = new ReportStorage(workspace, report);", "\n", "\n //constructor", - "\n public Ifrs17Reports (IWorkspace workspace, Systemorph.Vertex.Scopes.Proxy.IScopeFactory scopes, Systemorph.Vertex.Pivot.Builder.Interfaces.IPivotFactory report)", + "\n public Ifrs17 (IWorkspace workspace, Systemorph.Vertex.Scopes.Proxy.IScopeFactory scopes, Systemorph.Vertex.Pivot.Builder.Interfaces.IPivotFactory report)", "\n {", "\n this.scopes = scopes; ", "\n this.report = report; ", diff --git a/ifrs17/Utils/ApplicationMessage.ipynb b/ifrs17/Utils/ApplicationMessage.ipynb index 8f3dfbd6..e261b4a6 100644 --- a/ifrs17/Utils/ApplicationMessage.ipynb +++ b/ifrs17/Utils/ApplicationMessage.ipynb @@ -100,14 +100,13 @@ "cell_type": "code", "source": [ "public static ActivityLog Merge (this ActivityLog a, ActivityLog b) {", - "\n var errors = a.Errors.Concat(b.Errors).ToList();", "\n return a with { ", "\n Status = a.Status == ActivityLogStatus.Failed || b.Status == ActivityLogStatus.Failed ? ActivityLogStatus.Failed : ActivityLogStatus.Succeeded,", "\n StartDateTime = a.StartDateTime < b.StartDateTime ? a.StartDateTime : b.StartDateTime,", "\n FinishDateTime = a.FinishDateTime > b.FinishDateTime ? a.FinishDateTime : b.FinishDateTime,", - "\n Errors = errors,", - "\n Warnings = errors.Any() ? new List() : a.Warnings.Concat(b.Warnings).ToList(),", - "\n Infos = errors.Any() ? new List() : a.Infos.Concat(b.Infos).ToList(),", + "\n Errors = a.Errors.Concat(b.Errors).ToList(),", + "\n Warnings = a.Warnings.Concat(b.Warnings).ToList(),", + "\n Infos = a.Infos.Concat(b.Infos).ToList(),", "\n };", "\n}", "\n", diff --git a/ifrs17/Utils/ImportCalculationMethods.ipynb b/ifrs17/Utils/ImportCalculationMethods.ipynb index c5db1a05..f3238f31 100644 --- a/ifrs17/Utils/ImportCalculationMethods.ipynb +++ b/ifrs17/Utils/ImportCalculationMethods.ipynb @@ -139,6 +139,38 @@ "execution_count": 0, "outputs": [] }, + { + "cell_type": "code", + "source": [ + "public static IDataCube ComputeDiscountAndCumulate ( this IDataCube nominalRawVariables, double[] yearlyDiscountRates, AmountType[] amountTypes ) ", + "\n{", + "\n if(nominalRawVariables == null) return Enumerable.Empty().ToDataCube();", + "\n var periodTypeByAmountType = amountTypes.ToDictionary(x => x.SystemName, x => x.PeriodType);", + "\n ", + "\n return nominalRawVariables.Select(rv => {", + "\n var values = rv.Values.ToArray();", + "\n var cdcf = new double[values.Length];", + "\n periodTypeByAmountType.TryGetValue(rv.AmountType, out var period);", + "\n", + "\n if(period == PeriodType.BeginningOfPeriod)", + "\n {", + "\n for (var i = cdcf.Length - 1; i >= 0; i--)", + "\n cdcf[i] = values[i] + GetElementOrDefault(cdcf, i + 1) * GetElementOrDefault(yearlyDiscountRates, i/12);", + "\n }", + "\n else", + "\n { ", + "\n for (var i = cdcf.Length - 1; i >= 0; i--)", + "\n cdcf[i] = ( values[i] + GetElementOrDefault(cdcf, i + 1) ) * GetElementOrDefault(yearlyDiscountRates, i/12);", + "\n }", + "\n return rv with { Values = cdcf };", + "\n })", + "\n .ToDataCube();", + "\n}" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, { "cell_type": "markdown", "source": [ @@ -241,4 +273,4 @@ "outputs": [] } ] -} \ No newline at end of file +}