diff --git a/ifrs17-template/Files/DataNodes/DataNodeParameters_CH_2020_12.csv b/ifrs17-template/Files/DataNodes/DataNodeParameters_CH_2020_12.csv index 0e17cb6d..4d8c0860 100644 --- a/ifrs17-template/Files/DataNodes/DataNodeParameters_CH_2020_12.csv +++ b/ifrs17-template/Files/DataNodes/DataNodeParameters_CH_2020_12.csv @@ -3,17 +3,19 @@ ReportingNode,Year,Month CH,2020,12 ,, @@SingleDataNodeParameter,, -DataNode,PremiumAllocation, -GicComplex,0.8, -DT1.1,0.8, -DT1.2,0.8, -DT1.3,1, -DT1.4,0.8, -DT1.5,0.8, -DT2.1,0.8, -DT2.2,0.8, -DT3.1,0.8, -DT4.1,0.8, +DataNode,PremiumAllocation,CashFlowPeriodicity,InterpolationMethod,ReleasePattern0,ReleasePattern1,ReleasePattern2,ReleasePattern3,ReleasePattern4 +GicComplex,0.8,Monthly, +DT1.1,0.8,Monthly, +DT1.2,0.8,Monthly, +DT1.3,1,Monthly, +DT1.4,0.8,Monthly, +DT1.5,0.8,Monthly, +DT2.1,0.8,Monthly, +DT2.2,0.8,Monthly, +DT3.1,0.8,Monthly, +DT4.1,0.8,Monthly, +DT10.1,0,Yearly,Uniform, +DT10.2,0,Yearly,Uniform,1.41,1.14,0.87,0.58 ,, @@InterDataNodeParameter,, DataNode,LinkedDataNode,ReinsuranceCoverage diff --git a/ifrs17-template/Files/DataNodes/DataNodeStates_CH_2020_12.csv b/ifrs17-template/Files/DataNodes/DataNodeStates_CH_2020_12.csv index 42e0398a..982cc7ca 100644 --- a/ifrs17-template/Files/DataNodes/DataNodeStates_CH_2020_12.csv +++ b/ifrs17-template/Files/DataNodes/DataNodeStates_CH_2020_12.csv @@ -23,3 +23,5 @@ DTR1.4,Active, DTR2.1,Active, DTR2.2,Active, DTP1.1,Active, +DT10.1,Active, +DT10.2,Active, \ No newline at end of file diff --git a/ifrs17-template/Files/DataNodes/DataNodes_CH.csv b/ifrs17-template/Files/DataNodes/DataNodes_CH.csv index 6fae278b..7142e21a 100644 --- a/ifrs17-template/Files/DataNodes/DataNodes_CH.csv +++ b/ifrs17-template/Files/DataNodes/DataNodes_CH.csv @@ -10,6 +10,7 @@ DT2,DT2 NOCI,USD,ANN,BBA,, DT3,DT3 RunOff,USD,ANN,BBA,Default, DT4,DT4 OCI,USD,ANN,BBA,Default, DT5,DT5 Simple Import,USD,ANN,BBA,Default, +DT10,DT10 PPA,USD,ANN,PAA,Default, ,,,,,, @@GroupOfInsuranceContract,,,,,, SystemName,DisplayName,InsurancePortfolio,AnnualCohort,LiabilityType,Profitability, @@ -25,6 +26,8 @@ DT3.1,DT3.1 Runoff - PA 0.8,DT3,2020,LRC,P, DT4.1,DT4.1 CSM PA 0.8,DT4,2020,LRC,P, DT5.1,DT5.1 Simple Import on DT 4.1,DT5,2020,LRC,P, DTP1.1,DTP1.1 Projection,DT1,2020,LRC,P, +DT10.1,DT10.1 PAA,DT10,2020,LIC,P +DT10.2,DT10.1 PAA,DT10,2020,LRC,P ,,,,,, @@ReinsurancePortfolio,,,,,, SystemName,DisplayName,ContractualCurrency,LineOfBusiness,ValuationApproach,OciType, diff --git a/ifrs17-template/Files/TransactionalData/NominalCashflowsPAA_CH_2020_12.csv b/ifrs17-template/Files/TransactionalData/NominalCashflowsPAA_CH_2020_12.csv new file mode 100644 index 00000000..1cbf5e54 --- /dev/null +++ b/ifrs17-template/Files/TransactionalData/NominalCashflowsPAA_CH_2020_12.csv @@ -0,0 +1,7 @@ +@@Main,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +ReportingNode,Year,Month,Scenario,,,,,,,,,,,,,,,,,,,,,,,,,, +CH,2020,12,,,,,,,,,,,,,,,,,,,,,,,,,,, +@@Cashflow,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +DataNode,AmountType,EstimateType,AocType,Novelty,AccidentYear,CashFlowPeriodicity,InterpolationMethod,Values0,Values1,Values2,Values3,Values4,Values5,Values6,Values7,Values8,Values9,Values10,Values11,Values12,Values13,Values14,Values15,Values16,Values17,Values18,Values19,Values20,Values21,Values22,Values23 +DT10.2,DAE,BE,BOP,N,,Monthly,Uniform,1000,0,1300 +DT10.2,PR,BE,BOP,N,,Monthly,Uniform,1000, diff --git a/ifrs17-template/Import/InteractWithImportScopes/EvaluateImportScopes.ipynb b/ifrs17-template/Import/InteractWithImportScopes/EvaluateImportScopes.ipynb index a00173f3..87af97cf 100644 --- a/ifrs17-template/Import/InteractWithImportScopes/EvaluateImportScopes.ipynb +++ b/ifrs17-template/Import/InteractWithImportScopes/EvaluateImportScopes.ipynb @@ -202,14 +202,16 @@ { "cell_type": "code", "source": [ - "var ret = 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});", - "\nret.ToArray();" + "identities.First()" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var idByDn = identities.ToDictionaryGrouped(x => x.DataNode, x => x.ToArray());" ], "metadata": {}, "execution_count": 0, @@ -224,6 +226,87 @@ "execution_count": 0, "outputs": [] }, + { + "cell_type": "code", + "source": [ + "var ivs = Scopes.ForIdentities(identities, storage).ToScopes().SelectMany(x => x.PvLocked.Concat(x.PvCurrent)).ToArray();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var ivs = Scopes.ForIdentities(identities, storage).ToScopes().SelectMany(x => x.CumulatedNominal).ToArray();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var ivs = Scopes.ForIdentities(identities, storage).ToScopes().SelectMany(x => x.RaCurrent.Concat(x.RaLocked)).ToArray();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var ivs = Scopes.ForIdentities(identities, storage).ToScopes().SelectMany(x => x.Actual.Concat(x.AdvanceActual).Concat(x.OverdueActual)).ToArray();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var ivs = Scopes.ForIdentities(identities, storage).ToScopes().SelectMany(x => x.DeferrableActual).ToArray();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var ivs = Scopes.ForIdentities(identities, storage).ToScopes().SelectMany(x => x.BeEAForPremium.Concat(x.ActEAForPremium)).ToArray();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var ivs = Scopes.ForIdentities(identities, storage).ToScopes().SelectMany(x => x.BeEAForPremium.Concat(x.ActEAForPremium)).ToArray();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var ivs = Scopes.ForIdentities(identities, storage).ToScopes().SelectMany(x => x.AmortizationFactor.Concat(x.Csms).Concat(x.Loss)).ToArray();" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, { "cell_type": "code", "source": [ diff --git a/ifrs17-template/Test/Data/IfrsVariableBenchmarks/BM_CH_2020_12__F.csv b/ifrs17-template/Test/Data/IfrsVariableBenchmarks/BM_CH_2020_12__F.csv index 1edaa670..2bbd39c7 100644 --- a/ifrs17-template/Test/Data/IfrsVariableBenchmarks/BM_CH_2020_12__F.csv +++ b/ifrs17-template/Test/Data/IfrsVariableBenchmarks/BM_CH_2020_12__F.csv @@ -3,19 +3,19 @@ Month,ReportingNode,Scenario,Year 12,CH,,2020 @@F AccidentYear,AmountType,AocType,DataNode,EconomicBasis,EstimateType,Novelty,Values0 -,,AM,DT1.1,L,F,C,0.65623 +,CU,AM,DT1.1,L,F,C,0.65623 ,,AM,DT1.2,L,F,C,1 -,,AM,DT1.3,L,F,C,0.65623 -,,AM,DT2.1,L,F,C,0.65623 +,CU,AM,DT1.3,L,F,C,0.65623 +,CU,AM,DT2.1,L,F,C,0.65623 ,,AM,DT2.2,L,F,C,1 -,,AM,DTR1.1,L,F,C,0.65623 +,CU,AM,DTR1.1,L,F,C,0.65623 ,,AM,DTR1.2,L,F,C,1 -,,AM,DTR2.1,L,F,C,0.65623 +,CU,AM,DTR2.1,L,F,C,0.65623 ,,AM,DTR2.2,L,F,C,1 -,,AM,DT3.1,L,F,C,0.65623 -,,AM,DT4.1,L,F,C,0.65623 -,,AM,DT1.4,L,F,C,0.65623 -,,AM,DT1.5,L,F,C,0.65623 -,,AM,DTR1.3,L,F,C,0.65623 -,,AM,DTR1.4,L,F,C,0.65623 +,CU,AM,DT3.1,L,F,C,0.65623 +,CU,AM,DT4.1,L,F,C,0.65623 +,CU,AM,DT1.4,L,F,C,0.65623 +,CU,AM,DT1.5,L,F,C,0.65623 +,CU,AM,DTR1.3,L,F,C,0.65623 +,CU,AM,DTR1.4,L,F,C,0.65623 ,,AM,DT5.1,L,F,C,0.65623 \ No newline at end of file diff --git a/ifrs17-template/Test/Data/IfrsVariableBenchmarks/BM_CH_2021_3__F.csv b/ifrs17-template/Test/Data/IfrsVariableBenchmarks/BM_CH_2021_3__F.csv index 9a7ba050..e8653719 100644 --- a/ifrs17-template/Test/Data/IfrsVariableBenchmarks/BM_CH_2021_3__F.csv +++ b/ifrs17-template/Test/Data/IfrsVariableBenchmarks/BM_CH_2021_3__F.csv @@ -3,18 +3,18 @@ Month,ReportingNode,Scenario,Year 3,CH,,2021 @@F AccidentYear,AmountType,AocType,DataNode,EconomicBasis,EstimateType,Novelty,Values0 -,,AM,DT1.1,L,F,C,0.32249 +,CU,AM,DT1.1,L,F,C,0.32249 ,,AM,DT1.2,L,F,C,1 -,,AM,DT1.3,L,F,C,0.32249 -,,AM,DT2.1,L,F,C,0.32249 +,CU,AM,DT1.3,L,F,C,0.32249 +,CU,AM,DT2.1,L,F,C,0.32249 ,,AM,DT2.2,L,F,C,1 -,,AM,DTR1.1,L,F,C,0.32249 +,CU,AM,DTR1.1,L,F,C,0.32249 ,,AM,DTR1.2,L,F,C,1 -,,AM,DTR2.1,L,F,C,0.32249 +,CU,AM,DTR2.1,L,F,C,0.32249 ,,AM,DTR2.2,L,F,C,1 ,,AM,DT3.1,L,F,C,1 -,,AM,DT4.1,L,F,C,0.32249 -,,AM,DT1.4,L,F,C,0.32249 -,,AM,DT1.5,L,F,C,0.32249 -,,AM,DTR1.3,L,F,C,0.32249 -,,AM,DTR1.4,L,F,C,0.32249 \ No newline at end of file +,CU,AM,DT4.1,L,F,C,0.32249 +,CU,AM,DT1.4,L,F,C,0.32249 +,CU,AM,DT1.5,L,F,C,0.32249 +,CU,AM,DTR1.3,L,F,C,0.32249 +,CU,AM,DTR1.4,L,F,C,0.32249 \ No newline at end of file diff --git a/ifrs17-template/Test/IfrsVariablesTest.ipynb b/ifrs17-template/Test/IfrsVariablesTest.ipynb index d3931f2b..5506bba7 100644 --- a/ifrs17-template/Test/IfrsVariablesTest.ipynb +++ b/ifrs17-template/Test/IfrsVariablesTest.ipynb @@ -186,7 +186,7 @@ "\n var computedNotExpected = computed.Where(x => x.Values.Any(y => Math.Abs(y) > BenchmarkPrecision)).Except(expected, comparer);", "\n if (expectedNotComputed.Any()){", "\n foreach(var element in expectedNotComputed){", - "\n errors.Add(new BenchmarkTestResult(\"Extra expected variable for: Partition \" + element.Partition + \", \" + element.ToIdentityString()));", + "\n errors.Add(new BenchmarkTestResult(\"Extra expected variable for: Partition \" + element.Partition + \", \" + element.ToIdentityString(), element.Values, null));", "\n }", "\n }", "\n if (computedNotExpected.Any()){", diff --git a/ifrs17/Import/2ImportScope-PresentValue.ipynb b/ifrs17/Import/2ImportScope-PresentValue.ipynb index dc8994f1..1149e59d 100644 --- a/ifrs17/Import/2ImportScope-PresentValue.ipynb +++ b/ifrs17/Import/2ImportScope-PresentValue.ipynb @@ -779,32 +779,7 @@ { "cell_type": "markdown", "source": [ - "## Coverage Units", - "\n", - "\nThe coverage unit (CU) of a GIC is introduced in the standard as the quantity of the service provided in that GIC. The service is", - "\nmeasured by considering the quantity of benefits provided as well as the expected coverage period of the GIC.", - "\n", - "\nThe cash flows of coverage units are retrieved from the discounted cash flows with [EstimateType](../DataModel/DataStructure#estimate-type) CU." - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "public interface CoverageUnitCashflow : IScope", - "\n{ ", - "\n [NotVisible] string EconomicBasis => GetContext();", - "\n ", - "\n [IdentityProperty][NotVisible][Dimension(typeof(AmountType))]", - "\n string AmountType => AmountTypes.CU;", - "\n ", - "\n [IdentityProperty][NotVisible][Dimension(typeof(EstimateType))]", - "\n string EstimateType => EstimateTypes.P; ", - "\n", - "\n double[] Values => GetScope((Identity, AmountType, EstimateType, (int?)null)).Values;", - "\n}" + "## Amortization Factor" ], "metadata": {}, "execution_count": 0, @@ -813,7 +788,15 @@ { "cell_type": "markdown", "source": [ - "## Amortization Factor" + "The calculation of the Amortization factors uses a release pattern defined in input. ", + "\nA generic pattern specific for a certain GIC can be input through the [Single Data Node Parameter](../DataModel/#data-node-parameters) through the Release Pattern fields. It is possible to also define release pattern specific for an AmountType. For example a coverage units pattern for the calculaiton of Contractual service margin, a premium pattern for the Premium allocation approach, and a deferral pattern for deferrable expenses. ", + "\nThe calculation gives priority to the specific pattern and falls back to the general pattern provided as Data node parameter if absent. ", + "\n", + "\n**Specific AmountType**", + "\n", + "\nFor valuation approaches BBA and VFA the coverage unit (CU) of a GIC is introduced in the standard as the quantity of the service provided in that GIC. The service is measured by considering the quantity of benefits provided as well as the expected coverage period of the GIC.", + "\n", + "\nThe cash flows of coverage units are retrieved from the discounted (with Locked-in, Current, or undiscounted) and cumulated cash flows with [EstimateType](../DataModel/DataStructure#estimate-type) P and [AmountType](../DataModel/DataStructure#amount-type) CU. The pattern for the AoC Step CL,C is considered. " ], "metadata": {}, "execution_count": 0, @@ -822,25 +805,20 @@ { "cell_type": "markdown", "source": [ - "For a certain GIC, the monthly Amortization Factors $\\text{Monthly }AF_i$ are computed from the cash flows of the underlying coverage unit for that GIC:", + "**Calculation**", + "\n", + "\nFor a certain GIC, the monthly Amortization Factors $\\text{Monthly }AF_i$ are computed from the provided pattern for that GIC:", "\n", "\n$$", - "\n\\text{Monthly }AF_i = Max\\left(0, 1 - \\frac{ \\text{Nominal}_i(CL)} {\\text{CDC}_i(CL) }\\right) ~.", + "\n\\text{Monthly }AF_i = Max\\left(0, 1 - \\frac{ \\text{Nominal}_i} {\\text{CDC}_i }\\right) ~.", "\n$$", "\n", "\nwhere:", "\n- $i$ denotes a monthly period;", - "\n- the nominal cash flows $\\text{Nominal}_i(CL)$ are the nominal cash flows of the coverage unit for the AoC Step **Combined Liability** (CL) (input data);", - "\n- and the corresponding cumulated discounted cash flows $\\text{CDC}_i$ are defined [above](#cumulated-discounted-cash-flows)." - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "markdown", - "source": [ - "" + "\n- the nominal pattern $\\text{Nominal}_i$ is the monthly nominal pattern provided as input data;", + "\n- $\\text{CDC}_i$ is the corresponding cumulated discounted cash flows as defined [above](#cumulated-discounted-cash-flows). The discounting factors (Locked-in, Current, Nominal or undiscounted) is controlled by the EconomicBasis parameter following Ifrs 17 standards : Locked-in for BBA, Current for VFA, Current for PAA-LIC or taken from [EconomicBasisDriver](../DataModel/DataStructure#data-node-parameters) when the choice is left to the user. ", + "\n", + "\nOccasionally, it is required to shift the relase pattern to a certain period in order to correctly compute the release. Here we allow the $\\text{Nominal}_i$ to be shifted arbitrarily. The shift is considered also in the calculationof the corresponding $\\text{CDC}_i$ term and it is controlled by the computation of the specific release (Deferral, Premium, Contractual service margin)." ], "metadata": {}, "execution_count": 0, @@ -849,15 +827,18 @@ { "cell_type": "code", "source": [ - "public interface MonthlyAmortizationFactorCashflow : IScope", + "public interface MonthlyAmortizationFactorCashflow : IScope<(ImportIdentity Id, string AmountType, int patternShift), ImportStorage>", "\n{", - "\n private double[] NominalCuCashflow => GetScope((Identity with {AocType = AocTypes.CL}, AmountTypes.CU, EstimateTypes.P, (int?)null)).Values;", - "\n private double[] DiscountedCuCashflow => Multiply(-1d, GetScope(Identity with {AocType = AocTypes.CL}, o => o.WithContext(EconomicBasis)).Values);", + "\n (string EffectiveAmountType, double[] Values) releasePattern => GetStorage().GetReleasePattern(Identity.Id, Identity.AmountType, Identity.patternShift);", + "\n", + "\n private PeriodType periodType => GetStorage().GetPeriodType(Identity.AmountType, EstimateTypes.P);", + "\n private double[] monthlyDiscounting => GetScope(Identity.Id).Discount;", + "\n private double[] cdcPattern => releasePattern.Values.ComputeDiscountAndCumulate(monthlyDiscounting, periodType); ", "\n ", "\n [NotVisible] string EconomicBasis => GetContext();", "\n ", - "\n double[] MonthlyAmortizationFactors => Identity.AocType switch {", - "\n AocTypes.AM when NominalCuCashflow.Any() => NominalCuCashflow.Zip(DiscountedCuCashflow, //Extract to an other scope with month in the identity to avoid Zip?", + "\n double[] MonthlyAmortizationFactors => Identity.Id.AocType switch {", + "\n AocTypes.AM when releasePattern.Values?.Any() ?? false => releasePattern.Values.Zip(cdcPattern, //Extract to an other scope with month in the identity to avoid Zip?", "\n (nominal, discountedCumulated) => Math.Abs(discountedCumulated) >= Precision ? Math.Max(0, 1 - nominal / discountedCumulated) : 0).ToArray(),", "\n _ => Enumerable.Empty().ToArray(),", "\n };", @@ -887,15 +868,15 @@ { "cell_type": "code", "source": [ - "public interface CurrentPeriodAmortizationFactor : IScope", + "public interface CurrentPeriodAmortizationFactor : IScope<(ImportIdentity Id, string AmountType, int patternShift), ImportStorage>", "\n{", "\n static ApplicabilityBuilder ScopeApplicabilityBuilder(ApplicabilityBuilder builder) =>", "\n builder.ForScope(s => ", "\n s.WithApplicability(x => x.GetStorage().ImportFormat != ImportFormats.Cashflow", - "\n || x.GetStorage().IsSecondaryScope(x.Identity.DataNode)));", + "\n || x.GetStorage().IsSecondaryScope(x.Identity.Id.DataNode)));", "\n", - "\n private int shift => GetStorage().GetShift(Identity.ProjectionPeriod);", - "\n private int timeStep => GetStorage().GetTimeStep(Identity.ProjectionPeriod);", + "\n private int shift => GetStorage().GetShift(Identity.Id.ProjectionPeriod);", + "\n private int timeStep => GetStorage().GetTimeStep(Identity.Id.ProjectionPeriod);", "\n private double amortizedFactor => GetScope(Identity)", "\n .MonthlyAmortizationFactors", "\n .Skip(shift)", @@ -906,12 +887,15 @@ "\n [NotVisible] string EconomicBasis => GetContext();", "\n", "\n string EstimateType => EstimateTypes.F;", + "\n string EffectiveAmountType => GetScope(Identity).releasePattern.EffectiveAmountType;", "\n double Value => 1d - amortizedFactor;", "\n}", "\n", - "\npublic interface AmfFromIfrsVariable : CurrentPeriodAmortizationFactor", - "\n{", - "\n double CurrentPeriodAmortizationFactor.Value => GetStorage().GetValue(Identity, (string)null, EstimateType, EconomicBasis, (int?)null, Identity.ProjectionPeriod);", + "\npublic interface AmfFromIfrsVariable : CurrentPeriodAmortizationFactor{", + "\n private double amortizationFactorForAmountType => GetStorage().GetValue(Identity.Id, Identity.AmountType, EstimateType, EconomicBasis, Identity.patternShift == 0 ? null : Identity.patternShift, Identity.Id.ProjectionPeriod);", + "\n double CurrentPeriodAmortizationFactor.Value => Math.Abs(amortizationFactorForAmountType) >= Precision", + "\n ? amortizationFactorForAmountType ", + "\n : GetStorage().GetValue(Identity.Id, null, EstimateType, EconomicBasis, Identity.patternShift == 0 ? null : Identity.patternShift, Identity.Id.ProjectionPeriod);", "\n}" ], "metadata": {}, diff --git a/ifrs17/Import/3ImportScope-Actuals.ipynb b/ifrs17/Import/3ImportScope-Actuals.ipynb index 35c5d9d3..6cf9e033 100644 --- a/ifrs17/Import/3ImportScope-Actuals.ipynb +++ b/ifrs17/Import/3ImportScope-Actuals.ipynb @@ -315,7 +315,7 @@ "\n", "\npublic interface AmortizationDeferrable : DeferrableActual", "\n{", - "\n private double AmortizationFactor => GetScope(Identity, o => o.WithContext(EconomicBasis)).Value;", + "\n private double AmortizationFactor => GetScope((Identity, AmountTypes.CU, 0), o => o.WithContext(EconomicBasis)).Value;", "\n private double AggregatedDeferrable => GetScope((Identity, InputSource.Actual)).Values", "\n .Sum(aocStep => GetScope(Identity with {AocType = aocStep.AocType, Novelty = aocStep.Novelty}).Value);", "\n double DeferrableActual.Value => -1d * AggregatedDeferrable * AmortizationFactor;", diff --git a/ifrs17/Import/4ImportScope-TechnicalMargin.ipynb b/ifrs17/Import/4ImportScope-TechnicalMargin.ipynb index 76305353..3b424f86 100644 --- a/ifrs17/Import/4ImportScope-TechnicalMargin.ipynb +++ b/ifrs17/Import/4ImportScope-TechnicalMargin.ipynb @@ -304,7 +304,7 @@ "\n static ApplicabilityBuilder ScopeApplicabilityBuilder(ApplicabilityBuilder builder) =>", "\n builder.ForScope(s => s.WithApplicability(x => x.Identity.ValuationApproach == ValuationApproaches.PAA)); ", "\n ", - "\n double TechnicalMargin.Value => -1d * AggregatedValue * GetScope(Identity, o => o.WithContext(EconomicBasis)).Value;", + "\n double TechnicalMargin.Value => -1d * AggregatedValue * GetScope((Identity, AmountTypes.CU, 0), o => o.WithContext(EconomicBasis)).Value;", "\n}", "\n", "\npublic interface TechnicalMarginForAmForPaa : TechnicalMargin", diff --git a/ifrs17/Import/5ImportScope-ToIfrsVar.ipynb b/ifrs17/Import/5ImportScope-ToIfrsVar.ipynb index 94dd2b44..1eb166db 100644 --- a/ifrs17/Import/5ImportScope-ToIfrsVar.ipynb +++ b/ifrs17/Import/5ImportScope-ToIfrsVar.ipynb @@ -205,7 +205,9 @@ "source": [ "public interface DeferrableToIfrsVariable: IScope", "\n{", - "\n IEnumerable DeferrableActual => GetScope(Identity).RepeatOnce().Select(x => ", + "\n IEnumerable DeferrableActual => GetStorage().DataNodeDataBySystemName[Identity.DataNode].LiabilityType == LiabilityTypes.LIC ", + "\n ? Enumerable.Empty()", + "\n : GetScope(Identity).RepeatOnce().Select(x => ", "\n new IfrsVariable{ EstimateType = x.EstimateType,", "\n DataNode = x.Identity.DataNode,", "\n AocType = x.Identity.AocType,", @@ -266,14 +268,15 @@ "\n{", "\n private string EconomicBasis => Identity.ValuationApproach == ValuationApproaches.VFA ? EconomicBases.C : EconomicBases.L;", "\n IEnumerable AmortizationFactor => Identity.AocType == AocTypes.AM", - "\n ? GetScope(Identity, o => o.WithContext(EconomicBasis))", + "\n ? GetScope((Identity, AmountTypes.CU, 0), o => o.WithContext(EconomicBasis))", "\n .RepeatOnce()", "\n .Select(x => new IfrsVariable{ EstimateType = x.EstimateType,", - "\n DataNode = x.Identity.DataNode,", - "\n AocType = x.Identity.AocType,", - "\n Novelty = x.Identity.Novelty,", + "\n DataNode = x.Identity.Id.DataNode,", + "\n AocType = x.Identity.Id.AocType,", + "\n Novelty = x.Identity.Id.Novelty,", + "\n AmountType = x.EffectiveAmountType, //??", "\n EconomicBasis = x.EconomicBasis,", - "\n Values = SetProjectionValue(x.Value, x.Identity.ProjectionPeriod),", + "\n Values = SetProjectionValue(x.Value, x.Identity.Id.ProjectionPeriod),", "\n Partition = GetStorage().TargetPartition", "\n })", "\n : Enumerable.Empty();", diff --git a/ifrs17/Import/ImportStorage.ipynb b/ifrs17/Import/ImportStorage.ipynb index ee2947d2..25000183 100644 --- a/ifrs17/Import/ImportStorage.ipynb +++ b/ifrs17/Import/ImportStorage.ipynb @@ -367,8 +367,32 @@ "\n return Math.Pow(1d + rate[period].Values[0], 1d / 12d) - 1d;", "\n }", "\n ", - "\n public double GetPremiumAllocationFactor(ImportIdentity id) => SingleDataNodeParametersByGoc.TryGetValue(id.DataNode, out var singleDataNodeParameter) ", - "\n ? singleDataNodeParameter[CurrentPeriod].PremiumAllocation : DefaultPremiumExperienceAdjustmentFactor;", + "\n public (string, double[]) GetReleasePattern (ImportIdentity identity, string amountType, int patternShift)", + "\n {", + "\n var patternFromCashflow = GetValues(identity with {AocType = AocTypes.CL, Novelty = Novelties.C}, amountType, EstimateTypes.P, (int?)null);", + "\n if (patternFromCashflow.Any())", + "\n return (amountType, Enumerable.Repeat(0d, patternShift).Concat(patternFromCashflow).ToArray());", + "\n ", + "\n double[] patternFromParameter = default;", + "\n if(!SingleDataNodeParametersByGoc.TryGetValue(identity.DataNode, out var dataNodeParameterByPeriod))", + "\n return (null, patternFromParameter);", + "\n", + "\n var annualCohort = DataNodeDataBySystemName[identity.DataNode].AnnualCohort;", + "\n var skipMonthsToCurrentReportingPeriod = MonthInAYear * (CurrentReportingPeriod.Year - annualCohort);", + "\n var monthlyPattern = dataNodeParameterByPeriod[CurrentPeriod].ReleasePattern.Interpolate(dataNodeParameterByPeriod[CurrentPeriod].CashFlowPeriodicity, dataNodeParameterByPeriod[CurrentPeriod].InterpolationMethod);", + "\n return (null, Enumerable.Repeat(0d, patternShift).Concat(monthlyPattern.Normalize()).Skip(skipMonthsToCurrentReportingPeriod).ToArray());", + "\n }", + "\n ", + "\n public double GetPremiumAllocationFactor(ImportIdentity id) => ", + "\n SingleDataNodeParametersByGoc.TryGetValue(id.DataNode, out var singleDataNodeParameter) ", + "\n ? singleDataNodeParameter[CurrentPeriod].PremiumAllocation : DefaultPremiumExperienceAdjustmentFactor;", + "\n ", + "\n public string GetEconomicBasisDriver(string dataNode) => ", + "\n SingleDataNodeParametersByGoc.TryGetValue(dataNode, out var singleDataNodeParameter)", + "\n ? singleDataNodeParameter[CurrentPeriod].EconomicBasisDriver : default;", + "\n ", + "\n public bool IsInceptionYear(string dataNode) => SingleDataNodeParametersByGoc.TryGetValue(dataNode, out var singleDataNodeParameter)", + "\n ? singleDataNodeParameter[CurrentPeriod].Year == CurrentReportingPeriod.Year : default;", "\n ", "\n // Data Node relationships", "\n public IEnumerable GetUnderlyingGic(ImportIdentity id) => !InterDataNodeParametersByGoc.TryGetValue(id.DataNode, out var interDataNodeParameters)", diff --git a/ifrs17/Import/Importers.ipynb b/ifrs17/Import/Importers.ipynb index f7eca041..ea6c34b1 100644 --- a/ifrs17/Import/Importers.ipynb +++ b/ifrs17/Import/Importers.ipynb @@ -1213,7 +1213,7 @@ "\n string economicBasisDriverInput = default;", "\n if(hasEconomicBasisDriverColumn)", "\n economicBasisDriverInput = datarow.Field(nameof(SingleDataNodeParameter.EconomicBasisDriver));", - "\n var economicBasisDriver = storage.ValidateEconomicBasisDriver(economicBasisDriverInput, dataNode);", + "\n var economicBasisDriver = storage.ValidateEconomicBasisDriver(economicBasisDriverInput, dataNode); ", "\n", "\n double[] releasePattern = default;", "\n if(hasReleasePattern)", diff --git a/ifrs17/Test/AggregateInterpolateTest.ipynb b/ifrs17/Test/DoubleArrayExtentionsTest.ipynb similarity index 77% rename from ifrs17/Test/AggregateInterpolateTest.ipynb rename to ifrs17/Test/DoubleArrayExtentionsTest.ipynb index c21656c2..efc12fc9 100644 --- a/ifrs17/Test/AggregateInterpolateTest.ipynb +++ b/ifrs17/Test/DoubleArrayExtentionsTest.ipynb @@ -214,6 +214,72 @@ "metadata": {}, "execution_count": 0, "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Normalize" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "public void CheckNormalizedArray(IEnumerable source, double[] benchmark)", + "\n{", + "\n var res = source.Normalize();", + "\n res.Should().BeEquivalentTo(benchmark);", + "\n}" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var array = new double[]{1,1,1};", + "\nvar benchmark = new double[]{1d/3d,1d/3d,1d/3d};", + "\nCheckNormalizedArray(array, benchmark);" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var array = new double[]{-1,-1,-1};", + "\nvar benchmark = new double[]{1d/3d,1d/3d,1d/3d};", + "\nCheckNormalizedArray(array, benchmark);" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var array = new double[]{-1,+1,-1,+1};", + "\nvar benchmark = Enumerable.Empty().ToArray();", + "\nCheckNormalizedArray(array, benchmark);" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "var array = new double[]{};", + "\nvar benchmark = Enumerable.Empty().ToArray();", + "\nCheckNormalizedArray(array, benchmark);" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] } ] } \ No newline at end of file diff --git a/ifrs17/Test/TechnicalMarginTest.ipynb b/ifrs17/Test/TechnicalMarginTest.ipynb index 26c3e2b7..bd1ec8e3 100644 --- a/ifrs17/Test/TechnicalMarginTest.ipynb +++ b/ifrs17/Test/TechnicalMarginTest.ipynb @@ -320,7 +320,7 @@ "\n basicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Values = new double[] {15.0}},", "\n basicIfrsVariable with {AocType = \"EV\", Novelty = \"N\", Values = new double[] {100.0}},", "\n basicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Values = new double[] {100.0}},", - "\n basicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = null},", + "\n basicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = \"CU\"},", "\n };", "\n", "\nvar csmLcSwitch_benchmark = new Dictionary()", @@ -369,7 +369,7 @@ "\n basicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Values = new double[] {15.0}},", "\n basicIfrsVariable with {AocType = \"EV\", Novelty = \"N\", Values = new double[] {100.0}},", "\n basicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Values = new double[] {-500.0}},", - "\n basicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = null},", + "\n basicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = \"CU\"},", "\n };", "\n", "\nvar csmLcSwitch_benchmark = new Dictionary()", @@ -416,7 +416,7 @@ "\n basicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Values = new double[] {100.0}},", "\n basicIfrsVariable with {AocType = \"CF\", Novelty = \"N\", Values = new double[] {-10.0}},", "\n basicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Values = new double[] {-150.0}},", - "\n basicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = null},", + "\n basicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = \"CU\"},", "\n };", "\n", "\nvar csmLcSwitch_benchmark = new Dictionary()", @@ -468,7 +468,7 @@ "\n basicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Values = new double[] {150.0}},", "\n basicIfrsVariable with {AocType = \"EV\", Novelty = \"N\", Values = new double[] {-45.0}},", "\n basicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Values = new double[] {-30.0}},", - "\n basicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = null},", + "\n basicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = \"CU\"},", "\n };", "\n", "\nvar csmLcSwitch_benchmark = new Dictionary()", @@ -524,12 +524,12 @@ "\n grossBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Values = new double[] {-15.0}},", "\n grossBasicIfrsVariable with {AocType = \"EV\", Novelty = \"N\", Values = new double[] {-100.0}},", "\n grossBasicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Values = new double[] {+100.0}},", - "\n grossBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = null},", + "\n grossBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = \"CU\"},", "\n", "\n reinsBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Values = new double[] {100.0}},", "\n reinsBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Values = new double[] {-10.0}},", "\n reinsBasicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Values = new double[] {-30.0}},", - "\n reinsBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = null},", + "\n reinsBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = \"CU\"},", "\n };", "\n", "\nvar csmLcSwitch_benchmark = new Dictionary()", @@ -594,12 +594,12 @@ "\n grossBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Values = new double[] {100.0}},", "\n grossBasicIfrsVariable with {AocType = \"CF\", Novelty = \"N\", Values = new double[] {-10.0}},", "\n grossBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Values = new double[] {-150.0}}, ", - "\n grossBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = null},", + "\n grossBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = \"CU\"},", "\n", "\n reinsBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Values = new double[] {-100.0}},", "\n reinsBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Values = new double[] {-10.0}},", "\n reinsBasicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Values = new double[] {-30.0}},", - "\n reinsBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = null},", + "\n reinsBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = \"CU\"},", "\n };", "\n", "\n//Gross CSM-LC", @@ -661,12 +661,12 @@ "\nvar inputDataSet = new IfrsVariable[]{", "\n grossBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Values = new double[] {100.0}},", "\n grossBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Values = new double[] {-50.0}}, ", - "\n grossBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = null},", + "\n grossBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = \"CU\"},", "\n", "\n reinsBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Values = new double[] {-100.0}},", "\n reinsBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Values = new double[] {-10.0}},", "\n reinsBasicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Values = new double[] {-30.0}},", - "\n reinsBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = null},", + "\n reinsBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = \"CU\"},", "\n };", "\n", "\n//Gross CSM-LC", @@ -729,12 +729,12 @@ "\n grossBasicIfrsVariable with {AocType = \"IA\", Novelty = \"I\", Values = new double[] {10.0}}, ", "\n grossBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Values = new double[] {50.0}},", "\n grossBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Values = new double[] {-10.0}}, ", - "\n grossBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = null},", + "\n grossBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = \"CU\"},", "\n", "\n reinsBasicIfrsVariable with {AocType = \"BOP\", Novelty = \"N\", Values = new double[] {-100.0}},", "\n reinsBasicIfrsVariable with {AocType = \"IA\", Novelty = \"N\", Values = new double[] {-10.0}},", "\n reinsBasicIfrsVariable with {AocType = \"CL\", Novelty = \"C\", Values = new double[] {-30.0}},", - "\n reinsBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = null},", + "\n reinsBasicIfrsVariable with {AocType = \"AM\", Novelty = \"C\", Values = new double[] {0.5}, EstimateType = \"F\", AmountType = \"CU\"},", "\n };", "\n", "\n//Gross CSM-LC", diff --git a/ifrs17/Test/Tests.ipynb b/ifrs17/Test/Tests.ipynb index 99916537..5cb3f2c1 100644 --- a/ifrs17/Test/Tests.ipynb +++ b/ifrs17/Test/Tests.ipynb @@ -57,7 +57,7 @@ { "cell_type": "code", "source": [ - "#!eval-notebook \"AggregateInterpolateTest\"" + "#!eval-notebook \"DoubleArrayExtentionsTest\"" ], "metadata": {}, "execution_count": 0, diff --git a/ifrs17/Utils/Extensions.ipynb b/ifrs17/Utils/Extensions.ipynb index c048a8c2..41a92e0e 100644 --- a/ifrs17/Utils/Extensions.ipynb +++ b/ifrs17/Utils/Extensions.ipynb @@ -140,6 +140,19 @@ "execution_count": 0, "outputs": [] }, + { + "cell_type": "code", + "source": [ + "public static double[] Normalize(this IEnumerable source) {", + "\n var norm = source?.Sum() ?? 0d;", + "\n if(Math.Abs(norm) < Precision)", + "\n return Enumerable.Empty().ToArray();", + "\n return source.Select(v => v / norm).ToArray();}" + ], + "metadata": {}, + "execution_count": 0, + "outputs": [] + }, { "cell_type": "markdown", "source": [