Ported from the open-source IFRS 17 Calculation Engine — ifrs17/DataModel/DataStructure.ipynb — originally written for Systemorph Cloud.

The data model

The data model is the set of structures that hold the data. In the original engine it is a notebook of C# records persisted in a database. In the MeshWeaver port each structure is a NodeType of the Ifrs17 module, and each record is a node.

Dropped from the original: the base interfaces (IKeyed, IPartition, IPartitioned, IWithYearAndMonth, …), the abstract base classes and the partition records (IfrsPartition, PartitionByReportingNodeAndPeriod). They existed to store and slice data in the Systemorph Cloud database. On the mesh a node's path places it in a partition, and the queries in Ifrs17/Engine/Source/Ifrs17DataSource.cs select by partition and node type.

Dimensions

Dimensions are data that can be given a short name — the system name — and that change slowly over time. Currencies are the typical example, with system names EUR, CHF and so on. Using dimensions has three advantages:

In the port the system name is the node id and the display name is the node name.

Hierarchical dimensions

A hierarchical dimension gives each member an optional parent — the legal structure of a company, for instance, where reporting nodes roll up to their parents. The original tracks a level per member. The port stores the parent on the member (a Parent property) and resolves the tree into ancestor and descendant lookups (Hierarchy in Ifrs17/Engine/Source/Identities.cs).

Amount type — AmountType

The amount type describes the nature of a number: premiums, claims, expenses. It is hierarchical, so finer types can be introduced beneath a coarser one — claim expenses (CE) have parent claims (CL). Amount types name the cash flows: there are premium cash flows, claims cash flows and so on.

The original distinguishes amount types for cash flows and actuals (present-value amount types) from amount types for deferrable values (deferrable amount types): costs and expenses whose recognition can be deferred. Deferrable amounts are kept apart because they do not enter the CSM and loss-component calculation. The port has both: AmountType and DeferrableAmountType. Each carries a PeriodType — whether the amount falls due at the beginning (premiums) or the end (claims) of its period — which drives discounting.

The original also maps external cash-flow labels onto amount types through an ExternalId. The port has no such mapping.

Risk driver — RiskDriver

Risk drivers distinguish risk-adjustment figures by cause: mortality, disability, longevity. When only a total risk adjustment is used, no risk driver is needed.

Estimate type — EstimateType

The estimate type says what kind of figure a number is: BE for a best-estimate present value, RA for a risk adjustment, C for a contractual service margin, L for a loss component, A for an actual, and so on. In the port each estimate type also states its InputSource (which import supplies it), its StructureType (whether it is presented through the AoC chain) and its PeriodType.

Novelty — Novelty

Novelty describes how new the business is: I (in force), N (new business) and C (combined).

AoC type — AocType

The AoC type describes one kind of analysis-of-change step: amortization (AM), cash flow (CF), combined liabilities (CL) and so on. It is hierarchical: the yield-curve update (YCU) and the credit-risk update (CRU) sit under the financial assumption update (FAU).

The combined liabilities step CL captures the difference between the sum of the relevant previous steps and the end-of-period step, so changes no other step explains show up there. The nominal cash flows supplied for it are the projection for the end of the period. The step is special in several ways:

P&L and balance-sheet variable types — PnlVariableType, BsVariableType

The P&L variable type describes the sections of the profit-and-loss statement and their hierarchy; the balance-sheet variable type describes the analysis of change of the balance-sheet reports. The port has both dimensions; no report uses them yet. The original's accounting variable type, for the accounting events posted to an accounting file, is not ported.

Scenario — Scenario

A scenario names a set of stressed assumptions for sensitivity analysis. The default scenario, with no stress applied, is the best estimate; its identifier is the empty string, so inputs need not name it.

The original engine has these rules for scenarios:

In the port the scenario dimension exists and the parameter records (YieldCurve, ExchangeRate, CreditDefaultRate, PartnerRating, DataNodeState, DataNodeParameter) carry a Scenario property. The engine's storage (Ifrs17/Engine/Source/ImportStorage.cs) does not filter by scenario or fall back to the best estimate. None of the rules above is implemented yet.

Line of business — LineOfBusiness

The line of business classifies insurance business the usual way — a market- or company-specific blend of the risk covered, first- or third-party cover, product type and so on. Motor, property and endowment are typical. It is hierarchical.

Currency — Currency

Currencies are identified by their ISO codes: EUR, CHF, USD.

Economic basis — EconomicBasis

The economic basis is the discounting used in a calculation: N (nominal, no discounting), C (current) or L (locked-in).

Valuation approach — ValuationApproach

The measurement model: BBA (building block approach), VFA (variable fee approach) or PAA (premium allocation approach).

Liability type — LiabilityType

Distinguishes the liability for incurred claims (LIC) from the liability for remaining coverage (LRC).

OCI type — OciType

Describes how the financial contribution to the financial performance is split between profit and loss and other comprehensive income (OCI).

Profitability — Profitability

The profitability of a group of contracts at recognition: profitable, onerous, and so on.

Partner and credit risk rating — Partner, CreditRiskRating

The partner is the counterparty of a reinsurance contract. The credit risk rating is the rating a partner can hold.

Reporting node — ReportingNode

A reporting node is an element of the company's reporting structure. It is hierarchical, and data are supplied at the leaves. In the port a reporting node also carries its currency.

Projection configuration — ProjectionConfiguration

A projection period is defined by two parameters, both counted in months:

For the current year, year to date, the first quarter is Shift = 0, TimeStep = 3; the second quarter is TimeStep = 6, and so on. The port's worked example on The IFRS 17 formulas uses Shift = 0, TimeStep = 12.

Parameters

AoC step configuration — AocConfiguration

One row per combination of AoC type and novelty, valid from a year and month, says how that step behaves:

Column Meaning
DataType whether the step is supplied (Optional, Mandatory) or derived (Calculated, CalculatedTelescopic)
InputSource which import feeds the step: opening, actuals, cash flows, or a combination
FxPeriod which FX rate translates it (beginning of period, average, end of period)
YcPeriod which yield curve values it (previous or current period)
CdrPeriod which credit default rate it uses (previous or current period)
ValuationPeriod which point of the value array is its present value (see Present values)
RcPeriod which reinsurance coverage it uses (previous or current period)
Order where it sorts in the chain

The port's rows have exactly these columns. Because the step structure is data, adding a step is adding a row.

Exchange rate — ExchangeRate

Exchange rates over time, per currency and FX type (spot or average), as the value of one unit of the foreign currency in the group currency. They are updated every reporting period as part of the close; the last month of the period is used. A missing rate for the current period is an error — in the port too (ImportStorage.GetFx throws when a rate it needs is not held).

Credit default rate — CreditDefaultRate

Default rates over time for each credit risk rating, updated as part of the close. In the original they are entered monthly from January of the given year, and the last value holds for later years. The latest rate not after the closing period is used. When the current rate differs from the previous period's, the analysis of change shows the effect as its own step, the credit risk update (CRU). The rate is approximated as constant over time.

In the port the latest row not after the period is used, as in the original (ImportStorage.GetNonPerformanceRiskRate), and only the first value of that row is read — a single rate, constant over time.

Yield curve — YieldCurve

Forward-rate yield curves over time for each currency and scenario. Values are yearly: each one is the rate for a whole year, starting from the curve's year, and the last value holds for every later year. A group of contracts can name the curve it uses (YieldCurveName on GroupOfContract).

Which curve applies depends on the basis:

When the current curve differs from the previous period's, the analysis of change shows the effect as its own step, the yield curve update (YCU).

The port is stricter. ImportStorage.GetYearlyYieldCurve looks for a curve whose year and month equal the period exactly — the group's recognition period for L, the current or previous reporting period for C — and returns an empty curve when there is none. It does not fall back to the latest earlier curve.

Partner rating — PartnerRating

The credit risk rating of each partner over time, updated as part of the close. The default rate for each rating comes from the credit default rates.

Groups of contracts and their parameters

Data node

In the original a data node is a set of labels that place data: reporting node, scenario, contractual currency, functional currency, line of business, valuation approach and OCI type. In the port these labels live on the Portfolio, and a group of contracts inherits them from its portfolio (DataNodeData, built in Ifrs17DataSource.cs).

Portfolio — Portfolio

A portfolio is a set of groups of contracts; the link is set on the group. There are insurance portfolios and reinsurance portfolios (IsReinsurance on the port's portfolio).

Group of contracts — GroupOfContract

A group of contracts is a set of contracts with the same annual cohort, liability type, profitability and — for reinsurance — partner. Groups are collected into portfolios. A group of insurance contracts (GIC) has no partner; only a group of reinsurance contracts (GRIC) has one.

Data node state — DataNodeState

Tracks whether a group is active or inactive over time. In the original a state can only change from active to inactive.

Data node parameters — DataNodeParameter

Further parameters of a group, over time. In the original the latest set not after the closing period applies. The port takes the latest set per group regardless of the period (Ifrs17DataSource.cs), and stores it on the engine's storage; no scope reads it yet.

Parameter Meaning in the original In the port
PremiumAllocation the weight of premium included in the experience-adjustment step of the technical margin (LRC groups only) a property; not read by any scope
CashFlowPeriodicity the periodicity of the supplied cash flows; monthly by default a property; not read by any scope
InterpolationMethod how non-monthly cash flows are spread onto the monthly grid (uniformly, or all in the first month) a property; the helper Arithmetics.Interpolate implements both methods and is tested, but no scope calls it
ReleasePattern the factors that defer and amortize an amount type over the contract term, used when the cash flows carry no pattern of their own a property; not read by any scope
EconomicBasisDriver the basis used to discount a release pattern; defaults to locked-in for BBA, current for VFA and for PAA-LIC, nominal for PAA-LRC a property; not read by any scope. The default rule is ComputationHelper.GetDefaultEconomicBasisDriver, which the movement report uses for every group
ReinsuranceCoverage the share of the underlying gross business a reinsurance group is expected to reimburse; the cession for proportional contracts, estimated otherwise on the port's InterDataNodeParameter, linking a reinsurance group to an underlying group; not read by any scope

"Not read by any scope" is checked against Ifrs17/Engine/Source/ and Ifrs17/Report/Source/ at the time of writing.

Variables

Raw variable — RawVariable

Raw variables hold the cash flows as imported — after mappings, before any calculation. They are kept for audit and for recalculation. A raw variable is identified by its group of contracts, AoC type, novelty, estimate type, amount type and (for incurred claims) accident year, and holds a monthly array of values. In the original it also carries reporting node, scenario, year and month. The port's RawVariable has none of these, and they are not recovered from where the node sits either: Ifrs17DataSource reads the content of every raw variable it can reach and discards the path, the reporting period is an argument of the run, and ImportStorage.GetValues matches only the group, step, novelty, amount type, estimate type and accident year. So folder placement isolates neither periods nor scenarios — if one run reaches raw variables of the same group for two periods, their matching cash flows are summed, not selected by period.

IFRS variable — IfrsVariable

IFRS variables hold computed figures — present values, and in the original also actuals. They have the same identity as a raw variable plus the economic basis they were measured on. They are stored so that reports need not recompute them.

Import identity

The import identity is the key a calculation runs on: the group of contracts, the AoC type, the novelty, and whether the data are reinsurance. In the port it is ImportIdentity in Ifrs17/Engine/Source/Identities.cs. See Analysis-of-change structure.

Report variable

Report variables hold data after the calculation and before output. They are not persisted. In the port: ReportVariable in Ifrs17/Report/Source/ReportVariable.cs.