From c67a81464814b95033667378ee92a2cf49bc095d Mon Sep 17 00:00:00 2001 From: nnikolopoulos Date: Tue, 7 Feb 2023 14:03:37 +0100 Subject: [PATCH 1/8] Replace GetElementOrDefault with GetValidElement --- ifrs17/Import/ImportScopeCalculation.ipynb | 10 +++++----- ifrs17/Utils/Extensions.ipynb | 3 +-- ifrs17/Utils/ImportCalculationMethods.ipynb | 10 +++++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/ifrs17/Import/ImportScopeCalculation.ipynb b/ifrs17/Import/ImportScopeCalculation.ipynb index 5ea716a5..49f3a783 100644 --- a/ifrs17/Import/ImportScopeCalculation.ipynb +++ b/ifrs17/Import/ImportScopeCalculation.ipynb @@ -805,11 +805,11 @@ "\n switch (periodType) {", "\n case PeriodType.BeginningOfPeriod :", "\n for (var i = 0; i < parentDiscountedValues.Length; i++)", - "\n ret[i] = -1d * (parentDiscountedValues[i] - parentNominalValues[i]) * (GetElementOrDefault(monthlyInterestFactor, i/12) - 1d );", + "\n ret[i] = -1d * (parentDiscountedValues[i] - parentNominalValues[i]) * (GetValidElement(monthlyInterestFactor, i/12) - 1d );", "\n break;", "\n default :", "\n for (var i = 0; i < parentDiscountedValues.Length; i++)", - "\n ret[i] = -1d * parentDiscountedValues[i] * (GetElementOrDefault(monthlyInterestFactor, i/12) - 1d );", + "\n ret[i] = -1d * parentDiscountedValues[i] * (GetValidElement(monthlyInterestFactor, i/12) - 1d );", "\n break;", "\n }", "\n ", @@ -830,8 +830,8 @@ "\n var interestOnClaimsCashflowCreditRisk = new double[nominalClaimsCashflow.Length];", "\n var effectCreditRisk = new double[nominalClaimsCashflow.Length];", "\n for (var i = nominalClaimsCashflow.Length - 1; i >= 0; i--) {", - "\n interestOnClaimsCashflow[i] = 1 / GetElementOrDefault(monthlyInterestFactor, i/12) * (interestOnClaimsCashflow.ElementAtOrDefault(i + 1) + nominalClaimsCashflow[i] - nominalClaimsCashflow.ElementAtOrDefault(i + 1));", - "\n interestOnClaimsCashflowCreditRisk[i] = 1 / GetElementOrDefault(monthlyInterestFactor, i/12) * (Math.Exp(-nonPerformanceRiskRate) * interestOnClaimsCashflowCreditRisk.ElementAtOrDefault(i + 1) + nominalClaimsCashflow[i] - nominalClaimsCashflow.ElementAtOrDefault(i + 1));", + "\n interestOnClaimsCashflow[i] = 1 / GetValidElement(monthlyInterestFactor, i/12) * (interestOnClaimsCashflow.ElementAtOrDefault(i + 1) + nominalClaimsCashflow[i] - nominalClaimsCashflow.ElementAtOrDefault(i + 1));", + "\n interestOnClaimsCashflowCreditRisk[i] = 1 / GetValidElement(monthlyInterestFactor, i/12) * (Math.Exp(-nonPerformanceRiskRate) * interestOnClaimsCashflowCreditRisk.ElementAtOrDefault(i + 1) + nominalClaimsCashflow[i] - nominalClaimsCashflow.ElementAtOrDefault(i + 1));", "\n effectCreditRisk[i] = interestOnClaimsCashflow[i] - interestOnClaimsCashflowCreditRisk[i];", "\n }", "\n ", @@ -1698,7 +1698,7 @@ "\n private double[] monthlyInterestFactor => GetScope(Identity, o => o.WithContext(EconomicBasis)).Interest;", "\n ", "\n private double interestAccretionFactor => Enumerable.Range(shift,timeStep)", - "\n .Select(i => GetElementOrDefault(monthlyInterestFactor, i/12))", + "\n .Select(i => GetValidElement(monthlyInterestFactor, i/12))", "\n .Aggregate(1d, (x, y) => x * y ) - 1d;", "\n ", "\n double TechnicalMargin.Value => AggregatedValue * interestAccretionFactor;", diff --git a/ifrs17/Utils/Extensions.ipynb b/ifrs17/Utils/Extensions.ipynb index d23cd61e..c2edd37f 100644 --- a/ifrs17/Utils/Extensions.ipynb +++ b/ifrs17/Utils/Extensions.ipynb @@ -75,8 +75,7 @@ { "cell_type": "code", "source": [ - "// because the default(T) is something else than the first/last element. What about \"static T GetValidElement(this IList array, int index)\"? ", - "\nstatic T GetElementOrDefault(this ICollection array, int index)", + "static T GetValidElement(this IList array, int index)", "\n{ ", "\n var count = array.Count;", "\n if (array == null || count == 0)", diff --git a/ifrs17/Utils/ImportCalculationMethods.ipynb b/ifrs17/Utils/ImportCalculationMethods.ipynb index 4e8270a2..2981da4a 100644 --- a/ifrs17/Utils/ImportCalculationMethods.ipynb +++ b/ifrs17/Utils/ImportCalculationMethods.ipynb @@ -109,12 +109,12 @@ "\n if(periodType == PeriodType.BeginningOfPeriod)", "\n {", "\n for (var i = nominalValues.Length - 1; i >= 0; i--)", - "\n ret[i] = nominalValues[i] + GetElementOrDefault(ret, i + 1) * GetElementOrDefault(monthlyDiscounting, i/12);", + "\n ret[i] = nominalValues[i] + GetValidElement(ret, i + 1) * GetValidElement(monthlyDiscounting, i/12);", "\n return ret;", "\n }", "\n ", "\n for (var i = nominalValues.Length - 1; i >= 0; i--)", - "\n ret[i] = ( nominalValues[i] + GetElementOrDefault(ret, i + 1) ) * GetElementOrDefault(monthlyDiscounting, i/12);", + "\n ret[i] = ( nominalValues[i] + GetValidElement(ret, i + 1) ) * GetValidElement(monthlyDiscounting, i/12);", "\n ", "\n return ret;", "\n}" @@ -130,7 +130,7 @@ "\n{ ", "\n return Enumerable.Range(0, nominalValues.Length)", "\n .Select( t => Enumerable.Range(t, nominalValues.Length-t)", - "\n .Select( tau => nominalValues[tau] * Math.Pow(GetElementOrDefault(monthlyDiscounting, t/12), tau-t+1) * (Math.Exp(-nonPerformanceRiskRate*(tau-t)) - 1) )", + "\n .Select( tau => nominalValues[tau] * Math.Pow(GetValidElement(monthlyDiscounting, t/12), tau-t+1) * (Math.Exp(-nonPerformanceRiskRate*(tau-t)) - 1) )", "\n .Sum() )", "\n .ToArray();", "\n}" @@ -155,12 +155,12 @@ "\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 cdcf[i] = values[i] + GetValidElement(cdcf, i + 1) * GetValidElement(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 cdcf[i] = ( values[i] + GetValidElement(cdcf, i + 1) ) * GetValidElement(yearlyDiscountRates, i/12);", "\n }", "\n return rv with { Values = cdcf };", "\n })", From b0306894e4b5f1c6783d1288c42e24bd468f2f7a Mon Sep 17 00:00:00 2001 From: nnikolopoulos Date: Wed, 8 Feb 2023 11:27:12 +0100 Subject: [PATCH 2/8] Rename array to collection --- ifrs17/Utils/Extensions.ipynb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ifrs17/Utils/Extensions.ipynb b/ifrs17/Utils/Extensions.ipynb index c2edd37f..77cb97eb 100644 --- a/ifrs17/Utils/Extensions.ipynb +++ b/ifrs17/Utils/Extensions.ipynb @@ -75,17 +75,17 @@ { "cell_type": "code", "source": [ - "static T GetValidElement(this IList array, int index)", + "static T GetValidElement(this ICollection collection, int index)", "\n{ ", - "\n var count = array.Count;", - "\n if (array == null || count == 0)", + "\n var count = collection.Count;", + "\n if (collection == null || count == 0)", "\n return default(T);", "\n", "\n return index < 0", - "\n ? array.ElementAt(0) // should this case be removed?", + "\n ? collection.ElementAt(0)", "\n : index < count", - "\n ? array.ElementAt(index)", - "\n : array.ElementAt(count -1);", + "\n ? collection.ElementAt(index)", + "\n : collection.ElementAt(count -1);", "\n}" ], "metadata": {}, From af369fba1d331f881bf15fa918048fcd07449be3 Mon Sep 17 00:00:00 2001 From: nnikolopoulos Date: Wed, 8 Feb 2023 17:29:52 +0100 Subject: [PATCH 3/8] Remove obsolete case --- ifrs17/Utils/Extensions.ipynb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ifrs17/Utils/Extensions.ipynb b/ifrs17/Utils/Extensions.ipynb index 77cb97eb..c2510411 100644 --- a/ifrs17/Utils/Extensions.ipynb +++ b/ifrs17/Utils/Extensions.ipynb @@ -81,11 +81,9 @@ "\n if (collection == null || count == 0)", "\n return default(T);", "\n", - "\n return index < 0", - "\n ? collection.ElementAt(0)", - "\n : index < count", - "\n ? collection.ElementAt(index)", - "\n : collection.ElementAt(count -1);", + "\n return index < count", + "\n ? collection.ElementAt(index)", + "\n : collection.ElementAt(count -1);", "\n}" ], "metadata": {}, From e334772e04e093fbead23af509a57f8492354b81 Mon Sep 17 00:00:00 2001 From: nnikolopoulos Date: Thu, 9 Feb 2023 16:20:14 +0100 Subject: [PATCH 4/8] Create error for negative index and apply it --- ifrs17/Constants/Validations.ipynb | 4 ++++ ifrs17/Utils/Extensions.ipynb | 3 +++ 2 files changed, 7 insertions(+) diff --git a/ifrs17/Constants/Validations.ipynb b/ifrs17/Constants/Validations.ipynb index 3fdcf95e..01723328 100644 --- a/ifrs17/Constants/Validations.ipynb +++ b/ifrs17/Constants/Validations.ipynb @@ -86,6 +86,8 @@ "\n NotSupportedAocStepReference, MultipleEoP,", "\n // Data completeness", "\n MissingDataAtPosting, MissingCombinedLiability, MissingCoverageUnit, ", + "\n // Index", + "\n NegativeIndex,", "\n // Default", "\n Generic", "\n};" @@ -169,6 +171,8 @@ "\n (Error.MissingDataAtPosting , 1) => $\"Missing imported data for {s[0]} DataNode.\",", "\n (Error.MissingCombinedLiability , 2) => $\"Missing Combined Liability AoC Type for DataNode {s[0]} and AmountType {s[1]}.\",", "\n (Error.MissingCoverageUnit , 1) => $\"Missing Coverage Unit cash flow for {s[0]} DataNode.\",", + "\n // Index", + "\n (Error.NegativeIndex , 0) => $\"Negative value for index.\",", "\n // Default", "\n (Error.Generic , _) => $\"{s[0]}\",", "\n (_ , _) => $\"Error not found.\"", diff --git a/ifrs17/Utils/Extensions.ipynb b/ifrs17/Utils/Extensions.ipynb index c2510411..96f83264 100644 --- a/ifrs17/Utils/Extensions.ipynb +++ b/ifrs17/Utils/Extensions.ipynb @@ -81,6 +81,9 @@ "\n if (collection == null || count == 0)", "\n return default(T);", "\n", + "\n if (index < 0)", + "\n ApplicationMessage.Log(Error.NegativeIndex);", + "\n", "\n return index < count", "\n ? collection.ElementAt(index)", "\n : collection.ElementAt(count -1);", From 7dbc51498f7ee7aed70ca7c035e021b3b45a8f4e Mon Sep 17 00:00:00 2001 From: nnikolopoulos Date: Thu, 9 Feb 2023 16:41:53 +0100 Subject: [PATCH 5/8] Better error message --- ifrs17/Constants/Validations.ipynb | 2 +- ifrs17/Utils/Extensions.ipynb | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ifrs17/Constants/Validations.ipynb b/ifrs17/Constants/Validations.ipynb index 01723328..0bd2a1e8 100644 --- a/ifrs17/Constants/Validations.ipynb +++ b/ifrs17/Constants/Validations.ipynb @@ -172,7 +172,7 @@ "\n (Error.MissingCombinedLiability , 2) => $\"Missing Combined Liability AoC Type for DataNode {s[0]} and AmountType {s[1]}.\",", "\n (Error.MissingCoverageUnit , 1) => $\"Missing Coverage Unit cash flow for {s[0]} DataNode.\",", "\n // Index", - "\n (Error.NegativeIndex , 0) => $\"Negative value for index.\",", + "\n (Error.NegativeIndex , 0) => $\" Index was out of range. Must be non-negative. (Parameter 'index')\",", "\n // Default", "\n (Error.Generic , _) => $\"{s[0]}\",", "\n (_ , _) => $\"Error not found.\"", diff --git a/ifrs17/Utils/Extensions.ipynb b/ifrs17/Utils/Extensions.ipynb index 96f83264..beea37c7 100644 --- a/ifrs17/Utils/Extensions.ipynb +++ b/ifrs17/Utils/Extensions.ipynb @@ -82,7 +82,10 @@ "\n return default(T);", "\n", "\n if (index < 0)", + "\n {", "\n ApplicationMessage.Log(Error.NegativeIndex);", + "\n return default;", + "\n }", "\n", "\n return index < count", "\n ? collection.ElementAt(index)", From 983fb00b681a14d65364fab2cf52f8580261fbf0 Mon Sep 17 00:00:00 2001 From: nnikolopoulos Date: Fri, 10 Feb 2023 10:36:19 +0100 Subject: [PATCH 6/8] Add .ToHashSet() in ApplicationMessage AcivityLog Mege --- ifrs17/Utils/ApplicationMessage.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ifrs17/Utils/ApplicationMessage.ipynb b/ifrs17/Utils/ApplicationMessage.ipynb index 990dd62b..2d9e3d3e 100644 --- a/ifrs17/Utils/ApplicationMessage.ipynb +++ b/ifrs17/Utils/ApplicationMessage.ipynb @@ -110,9 +110,9 @@ "\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 = a.Errors.Concat(b.Errors).ToList(),", - "\n Warnings = a.Warnings.Concat(b.Warnings).ToList(),", - "\n Infos = a.Infos.Concat(b.Infos).ToList(),", + "\n Errors = a.Errors.Concat(b.Errors).ToHashSet().ToList(),", + "\n Warnings = a.Warnings.Concat(b.Warnings).ToHashSet().ToList(),", + "\n Infos = a.Infos.Concat(b.Infos).ToHashSet().ToList(),", "\n };", "\n}", "\n", From 3cf37078fa24f6d80745907c683e90a5962b87b6 Mon Sep 17 00:00:00 2001 From: nnikolopoulos Date: Fri, 10 Feb 2023 10:48:16 +0100 Subject: [PATCH 7/8] Implement feedback --- ifrs17/Import/ImportScopeCalculation.ipynb | 10 +++++----- ifrs17/Utils/ImportCalculationMethods.ipynb | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ifrs17/Import/ImportScopeCalculation.ipynb b/ifrs17/Import/ImportScopeCalculation.ipynb index 49f3a783..47c21764 100644 --- a/ifrs17/Import/ImportScopeCalculation.ipynb +++ b/ifrs17/Import/ImportScopeCalculation.ipynb @@ -805,11 +805,11 @@ "\n switch (periodType) {", "\n case PeriodType.BeginningOfPeriod :", "\n for (var i = 0; i < parentDiscountedValues.Length; i++)", - "\n ret[i] = -1d * (parentDiscountedValues[i] - parentNominalValues[i]) * (GetValidElement(monthlyInterestFactor, i/12) - 1d );", + "\n ret[i] = -1d * (parentDiscountedValues[i] - parentNominalValues[i]) * (monthlyInterestFactor.GetValidElement(i/12) - 1d );", "\n break;", "\n default :", "\n for (var i = 0; i < parentDiscountedValues.Length; i++)", - "\n ret[i] = -1d * parentDiscountedValues[i] * (GetValidElement(monthlyInterestFactor, i/12) - 1d );", + "\n ret[i] = -1d * parentDiscountedValues[i] * (monthlyInterestFactor.GetValidElement(i/12) - 1d );", "\n break;", "\n }", "\n ", @@ -830,8 +830,8 @@ "\n var interestOnClaimsCashflowCreditRisk = new double[nominalClaimsCashflow.Length];", "\n var effectCreditRisk = new double[nominalClaimsCashflow.Length];", "\n for (var i = nominalClaimsCashflow.Length - 1; i >= 0; i--) {", - "\n interestOnClaimsCashflow[i] = 1 / GetValidElement(monthlyInterestFactor, i/12) * (interestOnClaimsCashflow.ElementAtOrDefault(i + 1) + nominalClaimsCashflow[i] - nominalClaimsCashflow.ElementAtOrDefault(i + 1));", - "\n interestOnClaimsCashflowCreditRisk[i] = 1 / GetValidElement(monthlyInterestFactor, i/12) * (Math.Exp(-nonPerformanceRiskRate) * interestOnClaimsCashflowCreditRisk.ElementAtOrDefault(i + 1) + nominalClaimsCashflow[i] - nominalClaimsCashflow.ElementAtOrDefault(i + 1));", + "\n interestOnClaimsCashflow[i] = 1 / monthlyInterestFactor.GetValidElement(i/12) * (interestOnClaimsCashflow.ElementAtOrDefault(i + 1) + nominalClaimsCashflow[i] - nominalClaimsCashflow.ElementAtOrDefault(i + 1));", + "\n interestOnClaimsCashflowCreditRisk[i] = 1 / monthlyInterestFactor.GetValidElement(i/12) * (Math.Exp(-nonPerformanceRiskRate) * interestOnClaimsCashflowCreditRisk.ElementAtOrDefault(i + 1) + nominalClaimsCashflow[i] - nominalClaimsCashflow.ElementAtOrDefault(i + 1));", "\n effectCreditRisk[i] = interestOnClaimsCashflow[i] - interestOnClaimsCashflowCreditRisk[i];", "\n }", "\n ", @@ -1698,7 +1698,7 @@ "\n private double[] monthlyInterestFactor => GetScope(Identity, o => o.WithContext(EconomicBasis)).Interest;", "\n ", "\n private double interestAccretionFactor => Enumerable.Range(shift,timeStep)", - "\n .Select(i => GetValidElement(monthlyInterestFactor, i/12))", + "\n .Select(i => monthlyInterestFactor.GetValidElement(i/12))", "\n .Aggregate(1d, (x, y) => x * y ) - 1d;", "\n ", "\n double TechnicalMargin.Value => AggregatedValue * interestAccretionFactor;", diff --git a/ifrs17/Utils/ImportCalculationMethods.ipynb b/ifrs17/Utils/ImportCalculationMethods.ipynb index 2981da4a..02c03ab8 100644 --- a/ifrs17/Utils/ImportCalculationMethods.ipynb +++ b/ifrs17/Utils/ImportCalculationMethods.ipynb @@ -109,12 +109,12 @@ "\n if(periodType == PeriodType.BeginningOfPeriod)", "\n {", "\n for (var i = nominalValues.Length - 1; i >= 0; i--)", - "\n ret[i] = nominalValues[i] + GetValidElement(ret, i + 1) * GetValidElement(monthlyDiscounting, i/12);", + "\n ret[i] = nominalValues[i] + ret.GetValidElement(i + 1) * monthlyDiscounting.GetValidElement(i/12);", "\n return ret;", "\n }", "\n ", "\n for (var i = nominalValues.Length - 1; i >= 0; i--)", - "\n ret[i] = ( nominalValues[i] + GetValidElement(ret, i + 1) ) * GetValidElement(monthlyDiscounting, i/12);", + "\n ret[i] = ( nominalValues[i] + ret.GetValidElement(i + 1) ) * monthlyDiscounting.GetValidElement(i/12);", "\n ", "\n return ret;", "\n}" @@ -130,7 +130,7 @@ "\n{ ", "\n return Enumerable.Range(0, nominalValues.Length)", "\n .Select( t => Enumerable.Range(t, nominalValues.Length-t)", - "\n .Select( tau => nominalValues[tau] * Math.Pow(GetValidElement(monthlyDiscounting, t/12), tau-t+1) * (Math.Exp(-nonPerformanceRiskRate*(tau-t)) - 1) )", + "\n .Select( tau => nominalValues[tau] * Math.Pow(monthlyDiscounting.GetValidElement(t/12), tau-t+1) * (Math.Exp(-nonPerformanceRiskRate*(tau-t)) - 1) )", "\n .Sum() )", "\n .ToArray();", "\n}" @@ -155,12 +155,12 @@ "\n if(period == PeriodType.BeginningOfPeriod)", "\n {", "\n for (var i = cdcf.Length - 1; i >= 0; i--)", - "\n cdcf[i] = values[i] + GetValidElement(cdcf, i + 1) * GetValidElement(yearlyDiscountRates, i/12);", + "\n cdcf[i] = values[i] + cdcf.GetValidElement(i + 1) * yearlyDiscountRates.GetValidElement(i/12);", "\n }", "\n else", "\n { ", "\n for (var i = cdcf.Length - 1; i >= 0; i--)", - "\n cdcf[i] = ( values[i] + GetValidElement(cdcf, i + 1) ) * GetValidElement(yearlyDiscountRates, i/12);", + "\n cdcf[i] = ( values[i] + cdcf.GetValidElement(i + 1) ) * yearlyDiscountRates.GetValidElement(i/12);", "\n }", "\n return rv with { Values = cdcf };", "\n })", From 0ff6baa53940b818a537a9ea83727154c7fbf16f Mon Sep 17 00:00:00 2001 From: nnikolopoulos Date: Fri, 10 Feb 2023 12:31:26 +0100 Subject: [PATCH 8/8] Implement feedbackx2 --- ifrs17/Constants/Validations.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ifrs17/Constants/Validations.ipynb b/ifrs17/Constants/Validations.ipynb index 0bd2a1e8..2072f37f 100644 --- a/ifrs17/Constants/Validations.ipynb +++ b/ifrs17/Constants/Validations.ipynb @@ -172,7 +172,7 @@ "\n (Error.MissingCombinedLiability , 2) => $\"Missing Combined Liability AoC Type for DataNode {s[0]} and AmountType {s[1]}.\",", "\n (Error.MissingCoverageUnit , 1) => $\"Missing Coverage Unit cash flow for {s[0]} DataNode.\",", "\n // Index", - "\n (Error.NegativeIndex , 0) => $\" Index was out of range. Must be non-negative. (Parameter 'index')\",", + "\n (Error.NegativeIndex , 0) => $\"Index was out of range. Must be non-negative.\",", "\n // Default", "\n (Error.Generic , _) => $\"{s[0]}\",", "\n (_ , _) => $\"Error not found.\"",