From caf13b3e2dab856c5a371b356a899041ad1a0017 Mon Sep 17 00:00:00 2001 From: Davide Colleoni Date: Wed, 1 Feb 2023 14:47:21 +0100 Subject: [PATCH 1/5] debug import scopes --- .../Import/DebugCalculation/DebugScopes.ipynb | 247 ++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 ifrs17-template/Import/DebugCalculation/DebugScopes.ipynb diff --git a/ifrs17-template/Import/DebugCalculation/DebugScopes.ipynb b/ifrs17-template/Import/DebugCalculation/DebugScopes.ipynb new file mode 100644 index 00000000..5e547ab9 --- /dev/null +++ b/ifrs17-template/Import/DebugCalculation/DebugScopes.ipynb @@ -0,0 +1,247 @@ +{ + "metadata": { + "authors": [], + "kernelspec": { + "display_name": "Formula Framework", + "language": "C#", + "name": "C#" + }, + "language_info": { + "file_extension": ".cs", + "mimetype": "text/plain", + "name": "C#" + } + }, + "nbformat": 4, + "nbformat_minor": 5, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "

Debug Import Scope Calculation

" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "#!eval-notebook \"../CloseImportTemplate\"" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Args" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var reportingNode = \"CH\";", + "\nvar year = 2020;", + "\nvar month = 12;", + "\nvar importFormat = ImportFormats.Cashflow;", + "\nvar scenario = (string)null;", + "\n", + "\nImportArgs args = new ImportArgs(reportingNode, year, month, default(Periodicity), scenario, importFormat);", + "\nargs" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "Workspace.Initialize(x => x.FromSource(DataSource).DisableInitialization().DisableInitialization());" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# EstimateType to load" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var estimateTypes = (await DataSource.Query().ToArrayAsync());" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var estimateTypesByImportFormat = new Dictionary>(); ", + "\nestimateTypesByImportFormat[ImportFormats.Actual] = estimateTypes.Where(et => (et.InputSource == (InputSource)2 || et.InputSource == (InputSource)3) && ", + "\n et.SystemName != EstimateTypes.APA)", + "\n .Select(x => x.SystemName);", + "\nestimateTypesByImportFormat[ImportFormats.Cashflow] = estimateTypes.Where(et => et.InputSource == (InputSource)4 && ", + "\n et.SystemName != EstimateTypes.BEPA && et.SystemName != EstimateTypes.F)", + "\n .Select(x => x.SystemName);", + "\nestimateTypesByImportFormat[ImportFormats.Opening] = estimateTypes.Where(et => (et.InputSource == (InputSource)3 || et.InputSource == (InputSource)7) && ", + "\n et.SystemName != \"PL\")", + "\n .Select(x => x.SystemName);", + "\n", + "\nestimateTypesByImportFormat" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Load variables to workspace" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "DataSource.Partition.GetCurrent()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "await DataSource.Partition.SetAsync(args);", + "\nawait Workspace.Partition.SetAsync(args);" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "switch (args.ImportFormat)", + "\n{ ", + "\n case ImportFormats.Actual : ", + "\n await Workspace.UpdateAsync(await DataSource.Query().Where(x => estimateTypesByImportFormat[ImportFormats.Actual].Contains(x.EstimateType)).ToArrayAsync());", + "\n break;", + "\n case ImportFormats.Cashflow : ", + "\n await Workspace.UpdateAsync(await DataSource.Query().Where(x => estimateTypesByImportFormat[ImportFormats.Cashflow].Contains(x.EstimateType)).ToArrayAsync());", + "\n break;", + "\n default : ", + "\n await Workspace.UpdateAsync(await DataSource.Query().Where(x => estimateTypesByImportFormat[ImportFormats.Opening].Contains(x.EstimateType)).ToArrayAsync());", + "\n break;", + "\n}" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Set up copy of DataSource" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var customDataSource = Workspace.CreateNew();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "customDataSource.Initialize(x => x.FromSource(DataSource).DisableInitialization().DisableInitialization());" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Construct ImportStorage" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var storage = new ImportStorage(args, customDataSource, Workspace);", + "\nawait storage.InitializeAsync();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Create universe and Identities" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var universe = Scopes.ForStorage(storage).ToScope();", + "\nvar identities = universe.GetScopes(storage.DataNodesByImportScope[ImportScope.Primary]).SelectMany(s => s.Identities);" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var pvLocked = universe.GetScopes(identities)", + "\n .SelectMany(x => x.PresentValues)", + "\n .Select(x => new {Value= x.Value, ", + "\n Id = x.Identity.Id, ", + "\n AmoutType = x.Identity.AmountType,", + "\n EstimateType = x.Identity.EstimateType,", + "\n AccidentYear = x.Identity.AccidentYear});", + "\npvLocked" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + } + ] +} \ No newline at end of file From 50f326fb23bed9d63323ac2576394cc17d7c9b7d Mon Sep 17 00:00:00 2001 From: Davide Colleoni Date: Tue, 7 Feb 2023 16:11:27 +0100 Subject: [PATCH 2/5] enhance technical margin test - reproduce the bug - --- ifrs17/Test/TechnicalMarginTest.ipynb | 173 ++++++++++++++++++++++---- 1 file changed, 152 insertions(+), 21 deletions(-) diff --git a/ifrs17/Test/TechnicalMarginTest.ipynb b/ifrs17/Test/TechnicalMarginTest.ipynb index 1e60b92a..acc59124 100644 --- a/ifrs17/Test/TechnicalMarginTest.ipynb +++ b/ifrs17/Test/TechnicalMarginTest.ipynb @@ -59,10 +59,12 @@ { "cell_type": "code", "source": [ - "await DataSource.UpdateAsync(dt1.RepeatOnce());", + "await DataSource.UpdateAsync(new []{dt1, dtr1});", "\nawait DataSource.UpdateAsync(new[]{dt11});", - "\nawait DataSource.UpdateAsync(new[]{dt11State});", - "\nawait DataSource.UpdateAsync(new[]{dt11SingleParameter});" + "\nawait DataSource.UpdateAsync(new[]{dtr11});", + "\nawait DataSource.UpdateAsync(new[]{dt11State, dtr11State});", + "\nawait DataSource.UpdateAsync(new[]{dt11SingleParameter});", + "\nawait DataSource.UpdateAsync(new[]{dt11Inter});" ], "metadata": {}, "execution_count": 0, @@ -108,8 +110,9 @@ { "cell_type": "code", "source": [ - "await DataSource.UpdateAsync(previousPeriodPartition.RepeatOnce());", - "\nawait DataSource.UpdateAsync(partitionReportingNode.RepeatOnce());" + "await DataSource.UpdateAsync(partitionReportingNode.RepeatOnce());", + "\nawait DataSource.UpdateAsync(previousPeriodPartition.RepeatOnce());", + "\nawait DataSource.UpdateAsync(partition.RepeatOnce());" ], "metadata": {}, "execution_count": 0, @@ -127,25 +130,35 @@ { "cell_type": "code", "source": [ - "public async Task CheckSwitchLogicAsync(IEnumerable inputDataSet, Dictionary csmLcSwitchBenchmark)", + "public async Task CheckSwitchLogicAsync(IEnumerable inputDataSet, Dictionary csmLcSwitchBenchmark)", "\n{", "\n Activity.Start();", - "\n //Save test input data", + "\n var primaryDataNode = inputDataSet.Any(x => x.DataNode == groupOfReinsuranceContracts) ? groupOfReinsuranceContracts : groupOfInsuranceContracts;", + "\n var partitionId = inputDataSet.First().Partition;", + "\n", + "\n //Clean Workspace and Save test input data", + "\n await Workspace.DeleteAsync(await Workspace.Query().ToArrayAsync());", "\n await Workspace.UpdateAsync(inputDataSet);", "\n ", "\n //Set up import storage and test universe", - "\n var testStorage = new ImportStorage(previousArgs, DataSource, Workspace);", + "\n var partition = (await Workspace.Query().ToArrayAsync()).Single(x => x.Id == partitionId);", + "\n var args = new ImportArgs(partition.ReportingNode, partition.Year, partition.Month, Periodicity.Quarterly, partition.Scenario, ImportFormats.Actual);", + "\n var testStorage = new ImportStorage(args, DataSource, Workspace);", "\n await testStorage.InitializeAsync();", "\n var testUniverse = Scopes.ForStorage(testStorage).ToScope();", "\n ", - "\n var identities = testUniverse.GetScopes(testStorage.DataNodesByImportScope[ImportScope.Primary].Where(dn => dn == groupOfInsuranceContracts)).SelectMany(s => s.Identities);", - "\n var csm = testUniverse.GetScopes(identities, o => o.WithContext(\"C\")).Where(x => Math.Abs(x.Value) > Precision);", - "\n var lc = testUniverse.GetScopes(identities, o => o.WithContext(\"L\")).Where(x => Math.Abs(x.Value) > Precision);", + "\n var identities = testUniverse.GetScopes(testStorage.DataNodesByImportScope[ImportScope.Primary].Where(dn => dn == primaryDataNode)).SelectMany(s => s.Identities);", + "\n var csm = testUniverse.GetScopes(identities, o => o.WithContext(EstimateTypes.C)).Where(x => Math.Abs(x.Value) > Precision);", + "\n IEnumerable loss = Enumerable.Empty();", + "\n if (primaryDataNode == groupOfInsuranceContracts) loss = testUniverse.GetScopes(identities, o => o.WithContext(EstimateTypes.L)).Where(x => Math.Abs(x.Value) > Precision);", + "\n if (primaryDataNode == groupOfReinsuranceContracts) loss = testUniverse.GetScopes(identities, o => o.WithContext(EstimateTypes.LR)).Where(x => Math.Abs(x.Value) > Precision);", + "\n ", "\n //Clean up Workspace", - "\n await Workspace.DeleteAsync(await Workspace.Query().ToArrayAsync()); ", + "\n await Workspace.DeleteAsync(await Workspace.Query().ToArrayAsync());", + "\n await Workspace.DeleteAsync(inputDataSet);", "\n ", "\n var csmBenchmark = csmLcSwitchBenchmark.Where(x => Math.Abs(x.Value.valueCsm) > Precision).ToDictionary(x => x.Key, x => x.Value);", - "\n var lcBenchmark = csmLcSwitchBenchmark.Where(x => Math.Abs(x.Value.valueLc) > Precision).ToDictionary(x => x.Key, x => x.Value);", + "\n var lossBenchmark = csmLcSwitchBenchmark.Where(x => Math.Abs(x.Value.valueLoss) > Precision).ToDictionary(x => x.Key, x => x.Value);", "\n ", "\n ", "\n var errors = new List();", @@ -155,11 +168,11 @@ "\n .Select(x => $\"AocType:{x.Identity.AocType}, Novelty:{x.Identity.Novelty}, EstimateType:{x.EstimateType}, Value:{x.Value}.\");", "\n errors.Add( $\"{nameof(AllocateTechnicalMargin)} scope for CSM has more non zero items than benchmark. Extra computed variables : \\n {string.Join(\"\\n\", extraVariables)}.\" );", "\n }", - "\n if(lc.Count() > lcBenchmark.Count()) ", + "\n if(loss.Count() > lossBenchmark.Count()) ", "\n {", - "\n var extraVariables = lc.Where(x => !lcBenchmark.Keys.Contains(new AocStep(x.Identity.AocType, x.Identity.Novelty)))", + "\n var extraVariables = loss.Where(x => !lossBenchmark.Keys.Contains(new AocStep(x.Identity.AocType, x.Identity.Novelty)))", "\n .Select(x => $\"AocType:{x.Identity.AocType}, Novelty:{x.Identity.Novelty}, EstimateType:{x.EstimateType}, Value:{x.Value}, \");", - "\n errors.Add( $\"{nameof(AllocateTechnicalMargin)} scope for LC has more non zero items compared to benchmark: \\n {string.Join(\"\\n\", extraVariables)}.\" );", + "\n errors.Add( $\"{nameof(AllocateTechnicalMargin)} scope for LOSS(LC/LoReCo) has more non zero items compared to benchmark: \\n {string.Join(\"\\n\", extraVariables)}.\" );", "\n }", "\n ", "\n //Check ValueCsm", @@ -176,10 +189,10 @@ "\n if(Math.Abs(-1.0 * scopeSwitch.Value - kvp.Value.valueCsm) > Precision) ", "\n errors.Add( $\"Values not matching for AocType {kvp.Key.AocType} and Novelty {kvp.Key.Novelty}. Scope: Csm {-1 * scopeSwitch.Value}; Benchmark: Csm {kvp.Value.valueCsm}.\" );", "\n }", - "\n //Check ValueLc", - "\n foreach(var kvp in lcBenchmark)", + "\n //Check ValueLoss", + "\n foreach(var kvp in lossBenchmark)", "\n {", - "\n var scopeSwitch = lc.SingleOrDefault(y => y.Identity.AocType == kvp.Key.AocType && y.Identity.Novelty == kvp.Key.Novelty);", + "\n var scopeSwitch = loss.SingleOrDefault(y => y.Identity.AocType == kvp.Key.AocType && y.Identity.Novelty == kvp.Key.Novelty);", "\n ", "\n if(scopeSwitch == null)", "\n {", @@ -187,8 +200,8 @@ "\n continue;", "\n }", "\n ", - "\n if(Math.Abs(scopeSwitch.Value - kvp.Value.valueLc) > Precision) ", - "\n errors.Add( $\"Values not matching for AocType {kvp.Key.AocType} and Novelty {kvp.Key.Novelty}. Scope: Lc {scopeSwitch.Value}; Benchmark: Lc {kvp.Value.valueLc}.\" );", + "\n if(Math.Abs(scopeSwitch.Value - kvp.Value.valueLoss) > Precision) ", + "\n errors.Add( $\"Values not matching for AocType {kvp.Key.AocType} and Novelty {kvp.Key.Novelty}. Scope: Lc/LoReCo {scopeSwitch.Value}; Benchmark: Lc {kvp.Value.valueLoss}.\" );", "\n }", "\n ", "\n if(errors.Any()) ApplicationMessage.Log(Error.Generic, string.Join(\"\\n\", errors));", @@ -364,6 +377,124 @@ "execution_count": 0, "outputs": [] }, + { + "cell_type": "markdown", + "source": [ + "# Reinsurance" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var basicIfrsVariable = new IfrsVariable{Partition = previousPeriodPartition.Id, DataNode = groupOfInsuranceContracts, AccidentYear = null, AmountType = \"Cl\", EstimateType = \"BE\", EconomicBasis = \"L\"};", + "\nvar inputDataSet = new IfrsVariable[]{", + "\n basicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Value = -100.0},", + "\n basicIfrsVariable with {AocType = \"CF\", Novelty = \"N\", Value = 10.0},", + "\n basicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Value = -15.0},", + "\n basicIfrsVariable with {AocType = \"EV\", Novelty = \"N\", Value = -100.0},", + "\n basicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Value = +100.0},", + "\n basicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Value = 0.5, EstimateType = \"F\", AmountType = null},", + "\n };", + "\n", + "\nvar csmLcSwitch_benchmark = new Dictionary()", + "\n {", + "\n {new AocStep(\"BOP\",\"N\"),(100d, 0d)},", + "\n {new AocStep(\"IA\",\"N\"), (15d, 0d)},", + "\n {new AocStep(\"EV\",\"N\"), (100d, 0d)},", + "\n {new AocStep(\"CL\",\"C\"), (-100d, 0d)},", + "\n {new AocStep(\"AM\",\"C\"), (-57.5, 0d)},", + "\n {new AocStep(\"EOP\",\"C\"),(57.5, 0d)},", + "\n };", + "\n", + "\nvar activity = await CheckSwitchLogicAsync(inputDataSet, csmLcSwitch_benchmark);", + "\nactivity" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "DataSource.Query()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "partition" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "DataSource.Query().Single(x => x.Id == partition.Id)" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "previousArgs" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var reinsBasicIfrsVariable = new IfrsVariable{Partition = partition.Id, DataNode = groupOfReinsuranceContracts, AccidentYear = null, AmountType = \"PR\", EstimateType = \"BE\", EconomicBasis = \"L\"};", + "\nvar grossBasicIfrsVariable = new IfrsVariable{Partition = partition.Id, DataNode = groupOfInsuranceContracts, AccidentYear = null, AmountType = \"Cl\", EstimateType = \"BE\", EconomicBasis = \"L\"};", + "\nvar inputDataSet = new IfrsVariable[]{", + "\n grossBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Value = -100.0},", + "\n grossBasicIfrsVariable with {AocType = \"CF\", Novelty = \"N\", Value = 10.0},", + "\n grossBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Value = -15.0},", + "\n grossBasicIfrsVariable with {AocType = \"EV\", Novelty = \"N\", Value = -100.0},", + "\n grossBasicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Value = +100.0},", + "\n grossBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Value = 0.5, EstimateType = \"F\", AmountType = null},", + "\n", + "\n reinsBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Value = 100.0},", + "\n reinsBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Value = -10.0},", + "\n reinsBasicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Value = -30.0},", + "\n reinsBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Value = 0.5, EstimateType = \"F\", AmountType = null},", + "\n };", + "\n", + "\nvar csmLcSwitch_benchmark = new Dictionary()", + "\n {", + "\n {new AocStep(\"BOP\",\"N\"),(-100d, 0d)},", + "\n {new AocStep(\"IA\",\"N\"),(+10d, 0d)},", + "\n {new AocStep(\"CL\",\"C\"), (+30d, 0d)},", + "\n {new AocStep(\"AM\",\"C\"), (+30d, 0d)},", + "\n {new AocStep(\"EOP\",\"C\"),(-30d, 0d)},", + "\n };", + "\n" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var activity = await CheckSwitchLogicAsync(inputDataSet, csmLcSwitch_benchmark);", + "\n activity" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, { "cell_type": "code", "source": [ From 1cdac9385eb76dd1e20bec0cc63404bf183328db Mon Sep 17 00:00:00 2001 From: Davide Colleoni Date: Thu, 9 Feb 2023 13:47:34 +0100 Subject: [PATCH 3/5] fix and increase test coverage --- ifrs17/Import/ImportScopeCalculation.ipynb | 16 +- ifrs17/Test/TechnicalMarginTest.ipynb | 403 +++++++++++++++++---- 2 files changed, 348 insertions(+), 71 deletions(-) diff --git a/ifrs17/Import/ImportScopeCalculation.ipynb b/ifrs17/Import/ImportScopeCalculation.ipynb index 5ea716a5..f0f40ba7 100644 --- a/ifrs17/Import/ImportScopeCalculation.ipynb +++ b/ifrs17/Import/ImportScopeCalculation.ipynb @@ -1869,7 +1869,7 @@ "\n //Switch", "\n static ApplicabilityBuilder ScopeApplicabilityBuilder(ApplicabilityBuilder builder) => ", "\n builder.ForScope(s => s", - "\n .WithApplicability(x => x.Identity.IsReinsurance && x.Identity.AocType == AocTypes.CL) ", + "\n .WithApplicability(x => x.Identity.IsReinsurance && x.Identity.AocType == AocTypes.CL)", "\n .WithApplicability(x => x.Identity.IsReinsurance, ", "\n p => p.ForMember(s => s.ComputedEstimateType)", "\n .ForMember(s => s.HasSwitch))", @@ -1881,11 +1881,10 @@ "\n ", "\n [NotVisible] double AggregatedTechnicalMargin => GetScope(Identity).AggregatedValue; ", "\n [NotVisible] double TechnicalMargin => GetScope(Identity).Value;", - "\n ", "\n [NotVisible] string ComputedEstimateType => ComputeEstimateType(GetScope(Identity).AggregatedValue + TechnicalMargin);", "\n [NotVisible] bool HasSwitch => ComputedEstimateType != ComputeEstimateType(GetScope(Identity).AggregatedValue);", "\n ", - "\n //Allocate ", + "\n //Allocate", "\n [NotVisible] string EstimateType => GetContext();", "\n ", "\n double Value => (HasSwitch, EstimateType == ComputedEstimateType) switch {", @@ -1914,14 +1913,14 @@ "\n", "\npublic interface AllocateTechnicalMarginForReinsurance : AllocateTechnicalMargin", "\n{ ", - "\n //TODO add Reinsurance Coverage Update (RCU, Novelty=I) AocStep", + "\n //TODO add Reinsurance Coverage Update (RCU, Novelty=I) AocStep", "\n private IEnumerable underlyingGic => GetStorage().GetUnderlyingGic(Identity);", "\n ", "\n private double weightedUnderlyingTM => underlyingGic.Sum(gic => GetStorage().GetReinsuranceCoverage(Identity, gic) * ", - "\n GetScope(Identity with {DataNode = gic}).TechnicalMargin);", + "\n GetScope(Identity with {DataNode = gic}).Value);", "\n ", "\n private double weightedUnderlyingAggregatedTM => underlyingGic.Sum(gic => GetStorage().GetReinsuranceCoverage(Identity, gic) * ", - "\n GetScope(Identity with {DataNode = gic}).AggregatedTechnicalMargin);", + "\n GetScope(Identity with {DataNode = gic}).AggregatedValue);", "\n ", "\n private string ComputeReinsuranceEstimateType(double aggregatedFcf) => aggregatedFcf > Precision ? EstimateTypes.LR : EstimateTypes.C;", "\n ", @@ -1935,10 +1934,10 @@ "\n private IEnumerable underlyingGic => GetStorage().GetUnderlyingGic(Identity);", "\n ", "\n private double weightedUnderlyingTM => underlyingGic.Sum(gic => GetStorage().GetReinsuranceCoverage(Identity, gic) * ", - "\n GetScope(Identity with {DataNode = gic}).TechnicalMargin);", + "\n GetScope(Identity with {DataNode = gic}).Value);", "\n ", "\n private double weightedUnderlyingAggregatedTM => underlyingGic.Sum(gic => GetStorage().GetReinsuranceCoverage(Identity, gic) * ", - "\n GetScope(Identity with {DataNode = gic}).AggregatedTechnicalMargin);", + "\n GetScope(Identity with {DataNode = gic}).AggregatedValue);", "\n private string ComputeReinsuranceEstimateType(double aggregatedFcf) => aggregatedFcf > Precision ? EstimateTypes.LR : EstimateTypes.C;", "\n ", "\n string AllocateTechnicalMargin.ComputedEstimateType => ComputeReinsuranceEstimateType(weightedUnderlyingAggregatedTM + weightedUnderlyingTM);", @@ -1970,7 +1969,6 @@ "\n : (double)default; });", "\n", "\n [NotVisible] bool AllocateTechnicalMargin.HasSwitch => Math.Abs(balancingValue) > Precision;", - "\n ", "\n [NotVisible] double AllocateTechnicalMargin.AggregatedTechnicalMargin => balancingValue;", "\n}", "\n", diff --git a/ifrs17/Test/TechnicalMarginTest.ipynb b/ifrs17/Test/TechnicalMarginTest.ipynb index acc59124..cb036eba 100644 --- a/ifrs17/Test/TechnicalMarginTest.ipynb +++ b/ifrs17/Test/TechnicalMarginTest.ipynb @@ -121,7 +121,17 @@ { "cell_type": "markdown", "source": [ - "# Test" + "# Test Runner" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Error logger", + "\nIt compares the result of a calculation of a single Group of Contract against benchmarks and logs the errors." ], "metadata": {}, "execution_count": 0, @@ -130,37 +140,11 @@ { "cell_type": "code", "source": [ - "public async Task CheckSwitchLogicAsync(IEnumerable inputDataSet, Dictionary csmLcSwitchBenchmark)", + "public async Task> ErrorLoggerAsync(IEnumerable csm, ", + "\n IEnumerable loss, ", + "\n Dictionary csmBenchmark, ", + "\n Dictionary lossBenchmark)", "\n{", - "\n Activity.Start();", - "\n var primaryDataNode = inputDataSet.Any(x => x.DataNode == groupOfReinsuranceContracts) ? groupOfReinsuranceContracts : groupOfInsuranceContracts;", - "\n var partitionId = inputDataSet.First().Partition;", - "\n", - "\n //Clean Workspace and Save test input data", - "\n await Workspace.DeleteAsync(await Workspace.Query().ToArrayAsync());", - "\n await Workspace.UpdateAsync(inputDataSet);", - "\n ", - "\n //Set up import storage and test universe", - "\n var partition = (await Workspace.Query().ToArrayAsync()).Single(x => x.Id == partitionId);", - "\n var args = new ImportArgs(partition.ReportingNode, partition.Year, partition.Month, Periodicity.Quarterly, partition.Scenario, ImportFormats.Actual);", - "\n var testStorage = new ImportStorage(args, DataSource, Workspace);", - "\n await testStorage.InitializeAsync();", - "\n var testUniverse = Scopes.ForStorage(testStorage).ToScope();", - "\n ", - "\n var identities = testUniverse.GetScopes(testStorage.DataNodesByImportScope[ImportScope.Primary].Where(dn => dn == primaryDataNode)).SelectMany(s => s.Identities);", - "\n var csm = testUniverse.GetScopes(identities, o => o.WithContext(EstimateTypes.C)).Where(x => Math.Abs(x.Value) > Precision);", - "\n IEnumerable loss = Enumerable.Empty();", - "\n if (primaryDataNode == groupOfInsuranceContracts) loss = testUniverse.GetScopes(identities, o => o.WithContext(EstimateTypes.L)).Where(x => Math.Abs(x.Value) > Precision);", - "\n if (primaryDataNode == groupOfReinsuranceContracts) loss = testUniverse.GetScopes(identities, o => o.WithContext(EstimateTypes.LR)).Where(x => Math.Abs(x.Value) > Precision);", - "\n ", - "\n //Clean up Workspace", - "\n await Workspace.DeleteAsync(await Workspace.Query().ToArrayAsync());", - "\n await Workspace.DeleteAsync(inputDataSet);", - "\n ", - "\n var csmBenchmark = csmLcSwitchBenchmark.Where(x => Math.Abs(x.Value.valueCsm) > Precision).ToDictionary(x => x.Key, x => x.Value);", - "\n var lossBenchmark = csmLcSwitchBenchmark.Where(x => Math.Abs(x.Value.valueLoss) > Precision).ToDictionary(x => x.Key, x => x.Value);", - "\n ", - "\n ", "\n var errors = new List();", "\n if(csm.Count() > csmBenchmark.Count()) ", "\n {", @@ -201,10 +185,108 @@ "\n }", "\n ", "\n if(Math.Abs(scopeSwitch.Value - kvp.Value.valueLoss) > Precision) ", - "\n errors.Add( $\"Values not matching for AocType {kvp.Key.AocType} and Novelty {kvp.Key.Novelty}. Scope: Lc/LoReCo {scopeSwitch.Value}; Benchmark: Lc {kvp.Value.valueLoss}.\" );", + "\n errors.Add( $\"Values not matching for AocType {kvp.Key.AocType} and Novelty {kvp.Key.Novelty}. Scope: Lc/LoReCo {scopeSwitch.Value}; Benchmark: Lc/LoReCo {kvp.Value.valueLoss}.\" );", "\n }", "\n ", - "\n if(errors.Any()) ApplicationMessage.Log(Error.Generic, string.Join(\"\\n\", errors));", + "\n return errors;", + "\n}" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Computation runner" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "public async Task<(IEnumerable,IEnumerable)> ComputeScopesAsync (IEnumerable inputDataSet,", + "\n Guid partitionId, ", + "\n string primaryDataNode)", + "\n{", + "\n await Workspace.DeleteAsync(await Workspace.Query().ToArrayAsync());", + "\n await Workspace.UpdateAsync(inputDataSet);", + "\n", + "\n var partition = (await Workspace.Query().ToArrayAsync()).Single(x => x.Id == partitionId);", + "\n var args = new ImportArgs(partition.ReportingNode, partition.Year, partition.Month, Periodicity.Quarterly, partition.Scenario, ImportFormats.Actual);", + "\n var testStorage = new ImportStorage(args, DataSource, Workspace);", + "\n await testStorage.InitializeAsync();", + "\n var testUniverse = Scopes.ForStorage(testStorage).ToScope();", + "\n var identities = testUniverse.GetScopes(testStorage.DataNodesByImportScope[ImportScope.Primary].Where(dn => dn == primaryDataNode)).SelectMany(s => s.Identities);", + "\n var csm = testUniverse.GetScopes(identities, o => o.WithContext(EstimateTypes.C)).Where(x => Math.Abs(x.Value) > Precision);", + "\n IEnumerable loss = Enumerable.Empty();", + "\n if (primaryDataNode == groupOfInsuranceContracts) loss = testUniverse.GetScopes(identities, o => o.WithContext(EstimateTypes.L)).Where(x => Math.Abs(x.Value) > Precision);", + "\n if (primaryDataNode == groupOfReinsuranceContracts) loss = testUniverse.GetScopes(identities, o => o.WithContext(EstimateTypes.LR)).Where(x => Math.Abs(x.Value) > Precision);", + "\n ", + "\n await Workspace.DeleteAsync(await Workspace.Query().ToArrayAsync());", + "\n", + "\n return (csm, loss);", + "\n}" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Test runner ", + "\nprovided inputs and benchmarks computes the results and calls the error logger routine." + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "public async Task CheckSwitchLogicAsync(IEnumerable inputDataSet, ", + "\n Dictionary csmLcSwitchBenchmark,", + "\n Dictionary reinsuranceCsmLcSwitchBenchmark = null)", + "\n{", + "\n Activity.Start();", + "\n //SET UP COMPUTATION", + "\n var gross = (await DataSource.Query().ToArrayAsync()).Select(x => x.SystemName);", + "\n var dn = inputDataSet.Select(x => x.DataNode).ToHashSet();", + "\n var dnByType = dn.ToDictionary(x => gross.Contains(x) ? nameof(GroupOfInsuranceContract) : nameof(GroupOfReinsuranceContract), x => x);", + "\n var partitionId = inputDataSet.First().Partition;", + "\n ", + "\n //Gross", + "\n var errorsGross = new List();", + "\n if(dnByType.TryGetValue(nameof(GroupOfInsuranceContract), out var primaryDataNode)){", + "\n //set up bm", + "\n var csmBenchmark = csmLcSwitchBenchmark.Where(x => Math.Abs(x.Value.valueCsm) > Precision).ToDictionary(x => x.Key, x => x.Value);", + "\n var lossBenchmark = csmLcSwitchBenchmark.Where(x => Math.Abs(x.Value.valueLoss) > Precision).ToDictionary(x => x.Key, x => x.Value);", + "\n //Set up import storage and test universe", + "\n var (csm, loss) = await ComputeScopesAsync(inputDataSet, partitionId, primaryDataNode);", + "\n errorsGross = await ErrorLoggerAsync(csm, loss, csmBenchmark, lossBenchmark);", + "\n }", + "\n", + "\n //Reinsurance ", + "\n var errorsReins = new List();", + "\n if(dnByType.TryGetValue(nameof(GroupOfReinsuranceContract), out primaryDataNode)){", + "\n //set up bm", + "\n var csmBenchmark = reinsuranceCsmLcSwitchBenchmark.Where(x => Math.Abs(x.Value.valueCsm) > Precision).ToDictionary(x => x.Key, x => x.Value);", + "\n var lossBenchmark = reinsuranceCsmLcSwitchBenchmark.Where(x => Math.Abs(x.Value.valueLoss) > Precision).ToDictionary(x => x.Key, x => x.Value);", + "\n //Set up import storage and test universe", + "\n var (csm, loss) = await ComputeScopesAsync(inputDataSet, partitionId, primaryDataNode);", + "\n errorsReins = await ErrorLoggerAsync(csm, loss, csmBenchmark, lossBenchmark);", + "\n }", + "\n", + "\n //Clean up Workspace", + "\n await Workspace.DeleteAsync(await Workspace.Query().ToArrayAsync());", + "\n //await Workspace.DeleteAsync(inputDataSet);", + "\n ", + "\n if(errorsGross.Any()) ApplicationMessage.Log(Error.Generic, string.Join(\"Gross Errors: \\n\", errorsGross));", + "\n if(errorsReins.Any()) ApplicationMessage.Log(Error.Generic, string.Join(\"Reinsurance Errors : \\n\", errorsReins));", + "\n ", "\n return Activity.Finish();", "\n}" ], @@ -212,6 +294,24 @@ "execution_count": 0, "outputs": [] }, + { + "cell_type": "markdown", + "source": [ + "# Use cases" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Gross, no switch " + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, { "cell_type": "code", "source": [ @@ -252,6 +352,15 @@ "execution_count": 0, "outputs": [] }, + { + "cell_type": "markdown", + "source": [ + "## Gross switch at CL" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, { "cell_type": "code", "source": [ @@ -292,6 +401,15 @@ "execution_count": 0, "outputs": [] }, + { + "cell_type": "markdown", + "source": [ + "## Gross with switch without CL" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, { "cell_type": "code", "source": [ @@ -328,6 +446,17 @@ "execution_count": 0, "outputs": [] }, + { + "cell_type": "markdown", + "source": [ + "## Gross : multiple switch", + "\n", + "\nSwitch in the in force compenent, opposite switch in the new business component. CL AoC Step to correct the allocation of the combined section." + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, { "cell_type": "code", "source": [ @@ -380,7 +509,7 @@ { "cell_type": "markdown", "source": [ - "# Reinsurance" + "## Reinsurance no LoReCo with Gross no switch" ], "metadata": {}, "execution_count": 0, @@ -389,14 +518,20 @@ { "cell_type": "code", "source": [ - "var basicIfrsVariable = new IfrsVariable{Partition = previousPeriodPartition.Id, DataNode = groupOfInsuranceContracts, AccidentYear = null, AmountType = \"Cl\", EstimateType = \"BE\", EconomicBasis = \"L\"};", + "var reinsBasicIfrsVariable = new IfrsVariable{Partition = partition.Id, DataNode = groupOfReinsuranceContracts, AccidentYear = null, AmountType = \"PR\", EstimateType = \"BE\", EconomicBasis = \"L\"};", + "\nvar grossBasicIfrsVariable = new IfrsVariable{Partition = partition.Id, DataNode = groupOfInsuranceContracts, AccidentYear = null, AmountType = \"Cl\", EstimateType = \"BE\", EconomicBasis = \"L\"};", "\nvar inputDataSet = new IfrsVariable[]{", - "\n basicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Value = -100.0},", - "\n basicIfrsVariable with {AocType = \"CF\", Novelty = \"N\", Value = 10.0},", - "\n basicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Value = -15.0},", - "\n basicIfrsVariable with {AocType = \"EV\", Novelty = \"N\", Value = -100.0},", - "\n basicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Value = +100.0},", - "\n basicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Value = 0.5, EstimateType = \"F\", AmountType = null},", + "\n grossBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Value = -100.0},", + "\n grossBasicIfrsVariable with {AocType = \"CF\", Novelty = \"N\", Value = 10.0},", + "\n grossBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Value = -15.0},", + "\n grossBasicIfrsVariable with {AocType = \"EV\", Novelty = \"N\", Value = -100.0},", + "\n grossBasicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Value = +100.0},", + "\n grossBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Value = 0.5, EstimateType = \"F\", AmountType = null},", + "\n", + "\n reinsBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Value = 100.0},", + "\n reinsBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Value = -10.0},", + "\n reinsBasicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Value = -30.0},", + "\n reinsBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Value = 0.5, EstimateType = \"F\", AmountType = null},", "\n };", "\n", "\nvar csmLcSwitch_benchmark = new Dictionary()", @@ -409,8 +544,84 @@ "\n {new AocStep(\"EOP\",\"C\"),(57.5, 0d)},", "\n };", "\n", - "\nvar activity = await CheckSwitchLogicAsync(inputDataSet, csmLcSwitch_benchmark);", - "\nactivity" + "\nvar reinsCsmLcSwitch_benchmark = new Dictionary()", + "\n {", + "\n {new AocStep(\"BOP\",\"N\"),(-100d, 0d)},", + "\n {new AocStep(\"IA\",\"N\"),(+10d, 0d)},", + "\n {new AocStep(\"CL\",\"C\"), (+30d, 0d)},", + "\n {new AocStep(\"AM\",\"C\"), (+30d, 0d)},", + "\n {new AocStep(\"EOP\",\"C\"),(-30d, 0d)},", + "\n };", + "\n" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var activity = await CheckSwitchLogicAsync(inputDataSet, csmLcSwitch_benchmark, reinsCsmLcSwitch_benchmark);", + "\n activity" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "activity.Status.Should().Be(ActivityLogStatus.Succeeded);" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Reinsurance with Gross from [one switch](#gross-with-switch-without-cl) use case" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var reinsBasicIfrsVariable = new IfrsVariable{Partition = partition.Id, DataNode = groupOfReinsuranceContracts, AccidentYear = null, AmountType = \"PR\", EstimateType = \"BE\", EconomicBasis = \"L\"};", + "\nvar grossBasicIfrsVariable = new IfrsVariable{Partition = partition.Id, DataNode = groupOfInsuranceContracts, AccidentYear = null, AmountType = \"PR\", EstimateType = \"BE\", EconomicBasis = \"L\"};", + "\nvar basicIfrsVariable = new IfrsVariable{Partition = previousPeriodPartition.Id, DataNode = groupOfInsuranceContracts, AccidentYear = null, AmountType = \"PR\", EstimateType = \"BE\", EconomicBasis = \"L\"};", + "\nvar inputDataSet = new IfrsVariable[]{", + "\n grossBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Value = 100.0},", + "\n grossBasicIfrsVariable with {AocType = \"CF\", Novelty = \"N\", Value = -10.0},", + "\n grossBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Value = -150.0}, ", + "\n grossBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Value = 0.5, EstimateType = \"F\", AmountType = null},", + "\n", + "\n reinsBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Value = -100.0},", + "\n reinsBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Value = -10.0},", + "\n reinsBasicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Value = -30.0},", + "\n reinsBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Value = 0.5, EstimateType = \"F\", AmountType = null},", + "\n };", + "\n", + "\n//Gross CSM-LC", + "\nvar csmLcSwitch_benchmark = new Dictionary()", + "\n {", + "\n {new AocStep(\"BOP\",\"N\"), (0d, 100d)},", + "\n {new AocStep(\"IA\",\"N\"), (50d, -100d)},", + "\n {new AocStep(\"EA\",\"C\"), (8d, 0d)},", + "\n {new AocStep(\"AM\",\"C\"), (-29d, 0d)},", + "\n {new AocStep(\"EOP\",\"C\"), (29d, 0d)},", + "\n };", + "\n", + "\nvar reinsCsmLcSwitch_benchmark = new Dictionary()", + "\n {", + "\n {new AocStep(\"BOP\",\"N\"),(0d, -100d)},", + "\n {new AocStep(\"IA\",\"N\"),(110d, 100d)},", + "\n {new AocStep(\"CL\",\"C\"), (+30d, 0d)},", + "\n {new AocStep(\"AM\",\"C\"), (-70d, 0d)},", + "\n {new AocStep(\"EOP\",\"C\"),(+70d, 0d)},", + "\n };" ], "metadata": {}, "execution_count": 0, @@ -419,7 +630,8 @@ { "cell_type": "code", "source": [ - "DataSource.Query()" + "var activity = await CheckSwitchLogicAsync(inputDataSet, csmLcSwitch_benchmark, reinsCsmLcSwitch_benchmark);", + "\n activity" ], "metadata": {}, "execution_count": 0, @@ -428,7 +640,16 @@ { "cell_type": "code", "source": [ - "partition" + "activity.Status.Should().Be(ActivityLogStatus.Succeeded);" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Reinsurance with Gross all LC" ], "metadata": {}, "execution_count": 0, @@ -437,7 +658,36 @@ { "cell_type": "code", "source": [ - "DataSource.Query().Single(x => x.Id == partition.Id)" + "var reinsBasicIfrsVariable = new IfrsVariable{Partition = partition.Id, DataNode = groupOfReinsuranceContracts, AccidentYear = null, AmountType = \"PR\", EstimateType = \"BE\", EconomicBasis = \"L\"};", + "\nvar grossBasicIfrsVariable = new IfrsVariable{Partition = partition.Id, DataNode = groupOfInsuranceContracts, AccidentYear = null, AmountType = \"Cl\", EstimateType = \"BE\", EconomicBasis = \"L\"};", + "\nvar inputDataSet = new IfrsVariable[]{", + "\n grossBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Value = 100.0},", + "\n grossBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Value = -50.0}, ", + "\n grossBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Value = 0.5, EstimateType = \"F\", AmountType = null},", + "\n", + "\n reinsBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Value = -100.0},", + "\n reinsBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Value = -10.0},", + "\n reinsBasicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Value = -30.0},", + "\n reinsBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Value = 0.5, EstimateType = \"F\", AmountType = null},", + "\n };", + "\n", + "\n//Gross CSM-LC", + "\nvar csmLcSwitch_benchmark = new Dictionary()", + "\n {", + "\n {new AocStep(\"BOP\",\"N\"), (0d, 100d)},", + "\n {new AocStep(\"IA\",\"N\"), (0d, -50d)}, //IA of the gross has opposite sign wrt the others (triggers switching)", + "\n {new AocStep(\"AM\",\"C\"), (0d, -25d)},", + "\n {new AocStep(\"EOP\",\"C\"),(0d, 25d)},", + "\n };", + "\n", + "\nvar reinsCsmLcSwitch_benchmark = new Dictionary()", + "\n {", + "\n {new AocStep(\"BOP\",\"N\"),(0d, -100d)},", + "\n {new AocStep(\"IA\",\"N\"),(0d, -10d)},", + "\n {new AocStep(\"CL\",\"C\"), (0d, -30d)},", + "\n {new AocStep(\"AM\",\"C\"), (0d, 70d)},", + "\n {new AocStep(\"EOP\",\"C\"),(0d, -70d)},", + "\n };" ], "metadata": {}, "execution_count": 0, @@ -446,7 +696,26 @@ { "cell_type": "code", "source": [ - "previousArgs" + "var activity = await CheckSwitchLogicAsync(inputDataSet, csmLcSwitch_benchmark, reinsCsmLcSwitch_benchmark);", + "\nactivity" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "activity.Status.Should().Be(ActivityLogStatus.Succeeded);" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Reinsurance with Gross with CL balancing item" ], "metadata": {}, "execution_count": 0, @@ -458,28 +727,38 @@ "var reinsBasicIfrsVariable = new IfrsVariable{Partition = partition.Id, DataNode = groupOfReinsuranceContracts, AccidentYear = null, AmountType = \"PR\", EstimateType = \"BE\", EconomicBasis = \"L\"};", "\nvar grossBasicIfrsVariable = new IfrsVariable{Partition = partition.Id, DataNode = groupOfInsuranceContracts, AccidentYear = null, AmountType = \"Cl\", EstimateType = \"BE\", EconomicBasis = \"L\"};", "\nvar inputDataSet = new IfrsVariable[]{", - "\n grossBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Value = -100.0},", - "\n grossBasicIfrsVariable with {AocType = \"CF\", Novelty = \"N\", Value = 10.0},", - "\n grossBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Value = -15.0},", - "\n grossBasicIfrsVariable with {AocType = \"EV\", Novelty = \"N\", Value = -100.0},", - "\n grossBasicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Value = +100.0},", + "\n grossBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"I\", Value = 100.0, EstimateType = \"C\", AmountType = null},", + "\n grossBasicIfrsVariable with {AocType = \"IA\", Novelty = \"I\", Value = 10.0}, ", + "\n grossBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Value = 50.0},", + "\n grossBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Value = -10.0}, ", "\n grossBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Value = 0.5, EstimateType = \"F\", AmountType = null},", "\n", - "\n reinsBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Value = 100.0},", + "\n reinsBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Value = -100.0},", "\n reinsBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Value = -10.0},", "\n reinsBasicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Value = -30.0},", "\n reinsBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Value = 0.5, EstimateType = \"F\", AmountType = null},", "\n };", "\n", + "\n//Gross CSM-LC", "\nvar csmLcSwitch_benchmark = new Dictionary()", "\n {", - "\n {new AocStep(\"BOP\",\"N\"),(-100d, 0d)},", - "\n {new AocStep(\"IA\",\"N\"),(+10d, 0d)},", - "\n {new AocStep(\"CL\",\"C\"), (+30d, 0d)},", - "\n {new AocStep(\"AM\",\"C\"), (+30d, 0d)},", - "\n {new AocStep(\"EOP\",\"C\"),(-30d, 0d)},", + "\n {new AocStep(\"BOP\",\"I\"), (100d, 0d)},", + "\n {new AocStep(\"IA\",\"I\"), (0.049962543d, 0d)},", + "\n {new AocStep(\"BOP\",\"N\"), (0d, 50d)},", + "\n {new AocStep(\"IA\",\"N\"), (0d, -10d)},", + "\n {new AocStep(\"CL\",\"C\"), (-40d, -40d)},", + "\n {new AocStep(\"AM\",\"C\"), (-30.024981271d, 0d)},", + "\n {new AocStep(\"EOP\",\"C\"),(30.024981271d, 0d)},", "\n };", - "\n" + "\n", + "\nvar reinsCsmLcSwitch_benchmark = new Dictionary()", + "\n {", + "\n {new AocStep(\"BOP\",\"N\"),(0d, -100d)},", + "\n {new AocStep(\"IA\",\"N\"), (0d, -10d)},", + "\n {new AocStep(\"CL\",\"C\"), (140d, 110d)},", + "\n {new AocStep(\"AM\",\"C\"), (-70d, 0d)},", + "\n {new AocStep(\"EOP\",\"C\"),(70d, 0d)},", + "\n };" ], "metadata": {}, "execution_count": 0, @@ -488,8 +767,8 @@ { "cell_type": "code", "source": [ - "var activity = await CheckSwitchLogicAsync(inputDataSet, csmLcSwitch_benchmark);", - "\n activity" + "var activity = await CheckSwitchLogicAsync(inputDataSet, csmLcSwitch_benchmark, reinsCsmLcSwitch_benchmark);", + "\nactivity" ], "metadata": {}, "execution_count": 0, @@ -498,7 +777,7 @@ { "cell_type": "code", "source": [ - "" + "activity.Status.Should().Be(ActivityLogStatus.Succeeded);" ], "metadata": {}, "execution_count": 0, From 6efa96c7f658e15def1d7825d43ac4dcffbb2255 Mon Sep 17 00:00:00 2001 From: Davide Colleoni Date: Thu, 9 Feb 2023 16:25:49 +0100 Subject: [PATCH 4/5] clean up --- .../Import/DebugCalculation/DebugScopes.ipynb | 247 ------------------ 1 file changed, 247 deletions(-) delete mode 100644 ifrs17-template/Import/DebugCalculation/DebugScopes.ipynb diff --git a/ifrs17-template/Import/DebugCalculation/DebugScopes.ipynb b/ifrs17-template/Import/DebugCalculation/DebugScopes.ipynb deleted file mode 100644 index 5e547ab9..00000000 --- a/ifrs17-template/Import/DebugCalculation/DebugScopes.ipynb +++ /dev/null @@ -1,247 +0,0 @@ -{ - "metadata": { - "authors": [], - "kernelspec": { - "display_name": "Formula Framework", - "language": "C#", - "name": "C#" - }, - "language_info": { - "file_extension": ".cs", - "mimetype": "text/plain", - "name": "C#" - } - }, - "nbformat": 4, - "nbformat_minor": 5, - "cells": [ - { - "cell_type": "markdown", - "source": [ - "

Debug Import Scope Calculation

" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "#!eval-notebook \"../CloseImportTemplate\"" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "# Args" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "var reportingNode = \"CH\";", - "\nvar year = 2020;", - "\nvar month = 12;", - "\nvar importFormat = ImportFormats.Cashflow;", - "\nvar scenario = (string)null;", - "\n", - "\nImportArgs args = new ImportArgs(reportingNode, year, month, default(Periodicity), scenario, importFormat);", - "\nargs" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "Workspace.Initialize(x => x.FromSource(DataSource).DisableInitialization().DisableInitialization());" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "# EstimateType to load" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "var estimateTypes = (await DataSource.Query().ToArrayAsync());" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "var estimateTypesByImportFormat = new Dictionary>(); ", - "\nestimateTypesByImportFormat[ImportFormats.Actual] = estimateTypes.Where(et => (et.InputSource == (InputSource)2 || et.InputSource == (InputSource)3) && ", - "\n et.SystemName != EstimateTypes.APA)", - "\n .Select(x => x.SystemName);", - "\nestimateTypesByImportFormat[ImportFormats.Cashflow] = estimateTypes.Where(et => et.InputSource == (InputSource)4 && ", - "\n et.SystemName != EstimateTypes.BEPA && et.SystemName != EstimateTypes.F)", - "\n .Select(x => x.SystemName);", - "\nestimateTypesByImportFormat[ImportFormats.Opening] = estimateTypes.Where(et => (et.InputSource == (InputSource)3 || et.InputSource == (InputSource)7) && ", - "\n et.SystemName != \"PL\")", - "\n .Select(x => x.SystemName);", - "\n", - "\nestimateTypesByImportFormat" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "# Load variables to workspace" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "DataSource.Partition.GetCurrent()" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "await DataSource.Partition.SetAsync(args);", - "\nawait Workspace.Partition.SetAsync(args);" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "switch (args.ImportFormat)", - "\n{ ", - "\n case ImportFormats.Actual : ", - "\n await Workspace.UpdateAsync(await DataSource.Query().Where(x => estimateTypesByImportFormat[ImportFormats.Actual].Contains(x.EstimateType)).ToArrayAsync());", - "\n break;", - "\n case ImportFormats.Cashflow : ", - "\n await Workspace.UpdateAsync(await DataSource.Query().Where(x => estimateTypesByImportFormat[ImportFormats.Cashflow].Contains(x.EstimateType)).ToArrayAsync());", - "\n break;", - "\n default : ", - "\n await Workspace.UpdateAsync(await DataSource.Query().Where(x => estimateTypesByImportFormat[ImportFormats.Opening].Contains(x.EstimateType)).ToArrayAsync());", - "\n break;", - "\n}" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "# Set up copy of DataSource" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "var customDataSource = Workspace.CreateNew();" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "customDataSource.Initialize(x => x.FromSource(DataSource).DisableInitialization().DisableInitialization());" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "# Construct ImportStorage" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "var storage = new ImportStorage(args, customDataSource, Workspace);", - "\nawait storage.InitializeAsync();" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "# Create universe and Identities" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "var universe = Scopes.ForStorage(storage).ToScope();", - "\nvar identities = universe.GetScopes(storage.DataNodesByImportScope[ImportScope.Primary]).SelectMany(s => s.Identities);" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "var pvLocked = universe.GetScopes(identities)", - "\n .SelectMany(x => x.PresentValues)", - "\n .Select(x => new {Value= x.Value, ", - "\n Id = x.Identity.Id, ", - "\n AmoutType = x.Identity.AmountType,", - "\n EstimateType = x.Identity.EstimateType,", - "\n AccidentYear = x.Identity.AccidentYear});", - "\npvLocked" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - } - ] -} \ No newline at end of file From d17f4603d4d93279c9fefaa4ddb2e91fc0671786 Mon Sep 17 00:00:00 2001 From: Davide Colleoni Date: Fri, 10 Feb 2023 14:42:24 +0100 Subject: [PATCH 5/5] typos --- ifrs17/Test/TechnicalMarginTest.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ifrs17/Test/TechnicalMarginTest.ipynb b/ifrs17/Test/TechnicalMarginTest.ipynb index cb036eba..d40c3bfd 100644 --- a/ifrs17/Test/TechnicalMarginTest.ipynb +++ b/ifrs17/Test/TechnicalMarginTest.ipynb @@ -238,7 +238,7 @@ "cell_type": "markdown", "source": [ "## Test runner ", - "\nprovided inputs and benchmarks computes the results and calls the error logger routine." + "\nProvided inputs and benchmarks computes the results and calls the error logger routine." ], "metadata": {}, "execution_count": 0, @@ -451,7 +451,7 @@ "source": [ "## Gross : multiple switch", "\n", - "\nSwitch in the in force compenent, opposite switch in the new business component. CL AoC Step to correct the allocation of the combined section." + "\nSwitch in the in force component, opposite switch in the new business component. CL AoC Step to correct the allocation of the combined section." ], "metadata": {}, "execution_count": 0,