All business processes in the banking industry contain quite some specific business logic. Rather than coding this aggregated in one business application, it is wise to setup separate components for this logic. These components we will refer to as financial engines in this blog. Usually these engines can be quite easily isolated, as they receive a well-defined input and provide a well-defined output and typically don’t execute themselves any operational data manipulations (thus avoiding the data segregation issues which are probably the most complex issues to solve in a microservices architecture). These engines can manage the orchestration of the workflow (workflow engines), the characteristics of products (product engines), the next-best-offer/recommended products (recommendation engines), the generation of output notifications (notification engines - cfr. my blog "Notification management - Don’t underestimate its importance and complexity" - https://bankloch.blogspot.com/2020/03/notification-management-dont.html) or the authorization/role of a user (authorization engines). However in this blog we will focus on the engines which primarily do a financial calculation, the so-called financial calculation engines.
In financial services a lot of financial calculation engines exist, which determine based on (complex) algorithms and table lookups one or more output figures.
Obviously every banking domain has its specific calculation engines, like the KYC scoring engine in the customer management domain, the interest calculation engine in the account domain, the valuation, cash-flow forecasting, performance analysis or market risk (e.g. VaR) calculation engines in the securities space or the credit risk and collateral valuation engines in the credit space.
4 calculation engines are however present in almost every banking domain, i.e.
- A tax calculation engine for the calculation of taxes on transactions like VAT, withholding tax, stock exchange tax, tax on capital gains, stamp duty…
- A fee/commission engine for the calculation of fees charged by the bank, e.g. service fees, security transaction fees, custody fees, transfer fees, management fees…
- A pricing engine for the calculation of the price of a banking product, e.g. the calculation of an insurance premium or the calculation of the credit interest rate of a loan
- A discount engine for the calculation of a standard and maximum discount that can be applied for a specific transaction of a specific customer
The interesting thing about those calculation engines is that a certain abstraction from the business domain can be applied. By stripping away the business logic they can be abstracted to a technical calculation component, with several commonalities between all those calculation engines:
- They all receive a high number of input variables, like the type of banking product involved, customer segment, activity of the customer (e.g. number of transactions, number of products at the bank…), transaction amount, product duration, input channel (branch, web, mobile…)… A first step of the calculation engine will therefore be a validation of the quality of those input variables, e.g. has a value for all mandatory variables been provided, do all values fit the syntax validations…
- These validated variables are then translated into values (often via a lookup table managed by the business product owner) and then aggregated using pre-defined (but configurable) weights. This aggregated value will be a relative or absolute value.
- This resulting value can then still be capped with a minimum or maximum cap, which in its turn can also be calculated using multiple variables, a mechanism of lookups and a weighted aggregation. Apart from a capping, it might also be that a pro-rata calculation is done to take the notion of time into account.
- In the end the calculation engine outputs a 1 or more output values.
Obviously more complex algorithms are also possible, e.g. algorithms based on an optimization problem (cfr. my blog "Optimisation problems - Far from being a commodity" - https://bankloch.blogspot.com/2020/05/optimisation-problems-far-from-being.html) or using AI (cfr. my blog "AI in Financial Services - A buzzword that is here to stay!" - https://bankloch.blogspot.com/2020/09/ai-in-financial-services-buzzword-that.html).
On top of this common flow, they also have in common that ideally they should be composed of 3 parts:
Design module
The "Design" module allows to configure the parameters of the model used to perform the calculation. Ideally a business owner should have an easy front-end in order to manipulate the main parameters of the model, thus giving a high flexibility to the business.
This means following features should ideally be foreseen in the module:
- Authenticate/Login to the "Design" module. As these parameters can have a very strong impact on the bank’s business, this module should be well protected to avoid that anyone can make modifications to these parameters. In the same context it would be wise to foresee a 4-eyes principle for modifications (i.e. 1 user making the modification and another one validating the change).
- A user-friendly cockpit to visualize and update the parameterization, with good data validations and possibility to work on draft parameterizations, which are not yet published
- Support features like historization of parameterizations, input of parameterizations which only take effect as of a specific date, possibility to apply a parameterization only to a subset of customers (i.e. to support Canary and A/B testing) or the possibility to manage very specific derogations (e.g. individual derogations for large customers).
- Ideally also foresee a simulator tool to manually test a specific parameterization and potentially even execute a back-testing with the new parameterization.
Run module
The "Run" module is the actual execution platform, where the financial calculations are executed. This module is the heart of the engine and applies the defined model on the input parameters to calculate the output(s).
The "Run" module should support both "simulation" and "operational" mode. This makes no difference for the financial calculations itself, but it will be important to store this information, in order to split these 2 modes in the Monitoring/Analytics module.
The module should furthermore support both real-time individual calls (synchronous requests), but also executions of (large) batches (asynchronous requests). These batches can be used for back-testing, but also for other simulations and predictions or for pre-calculations (e.g. the credit scoring engine can be called in batch for all customers in order to pre-approve customers for a specific loan amount).
Operate/Monitor module
The "Operate/Monitor" module allows to follow-up the usage of the financial engine. This can be via a specific custom front-end on top of the engine or the engine can also expose certain metrics and end points for integration in specific monitoring (e.g. ELK stack, an APM tool like Datadog or a BAM tool like WSO2 BAM) and analytics/BI tools (e.g. Tableau, Power BI, Metabase, cumul.io…).
Ideally the following features should be available to end-user (i.e. either directly exposed by engine or via a Monitoring/Analytics tool):
- All executed calculations should be stored in the database of the engine, with the value of the input parameters, the calculated output(s), the used version of the parameterization and the calculation mode (i.e. simulation vs. operational and synchronous vs. asynchronous). Furthermore meta-data like the timestamp, requesting channel and potentially the requesting user should also be stored. Obviously it should be very easy to search in this dataset, in order to analyse specific cases, but also to proof to auditors that the engine works correctly and has no bias (no discrimination).
- The engine should also capture certain internal statistics, like failures to execute a calculation (due to invalid input, technical issues…) or the time spent on a calculation
- This stored and calculated data allows to expose different types of dashboards, like an engine monitoring dashboard (supervising the average and 50th/75th/90th/99th percentiles for calculation time or the number of errors occurring in the engine) or a business dashboard (showing the distribution of the input variables and/or calculated outputs)
As those financial calculation engines are not always the most visible (compared to apps and other front-end channel application), they are often overlooked when defining priorities in an IT roadmap. Nonetheless these calculation engines are the core of a financial services company and often contain strong differentiating "métier" knowledge of the bank. As such well-functioning and highly flexible financial calculation engines can be an important competitive differentiator.
Given the commonalities of different calculation engines (and the same applies for non-calculation engines) even across different business domains, it can be interesting to setup a central team building those engines (obviously supported by product owners of the individual business domains). This way the independence of those engines can be assured (other domains call them via well-documented APIs) and the commonalities between those engines can be maximum leveraged.