Part of Balans.bg (a platform containing specialized resources tailored to accountants and lawyers) was developing custom accounting and financial calculators. The need for these arises from the daily work of professionals - their clients often call them with repetitive requests. The most notable of them are on topics like employee or self-employed remuneration, sick leave, dynamic bonuses, work experience and so on, which take a sizable amount of time to do manually
Our task was to find a way to automate the solution to many of these requests and in the end, we managed to develop 30+ custom calculators for the platform. In this article, I am going to share one of the more inventive cases we handled - calculating the remuneration for an employment contract.
For simplification, I am going to note a few details first:
There are 4 types of remunerations when signing an employment contract in Bulgaria:
Base remuneration - the base amount, from which all calculations follow, called for short BR
Gross remuneration - calculated as BR + Work experience bonus as a percent of BR + any additional gross bonus (short GR)
Net remuneration - the amount an employee receives, calculated as GR - Insurances - Income tax, referenced later as NR
Budget for remuneration - the total amount an employer must spend for the contract, calculated as GR + Insurances (B for reference)
There are 3 types of bonuses an employer can give out to his employees:
Gross bonus - an amount, which is added to the gross remuneration in the contract
Net bonus - an amount, which is added to the net remuneration
Bonus for the total budget - an amount, which is added to the total budget
Bonuses can be taken into consideration in the calculations as:
An addition to the amount of their type (example - GR of 2000 leva with additional 200 leva gross bonus)
As part of the total amount they are a type of (example - GR of 2000 leva of which 200 leva is gross bonus)
Once a contract is signed, the BR can’t change - any bonus calculation that is given out at some point must increase the other 3 types of remunerations without changing the BR
With these remarks covered, we can move to the purpose of this article.
Specialists in Bulgaria often get asked the following kind of questions by their clients:
How much would it cost me to give out X amount of net salary?
I have an additional budget of X amount this year - how much net bonus would this provide for my employees?
The base salary of my employees is X amount - how much net would they receive if I give out an additional Y amount of gross bonus per employee?
The net remuneration of an employee is X amount - how much gross bonus should I give out to reach Y amount of net remuneration?
We can see that the main question clients ask is in the form “how to reach a remuneration of some type by providing remuneration and/or bonus of some different type”. Or, to put it in a more mathematical phrase, how to find the input of a function by knowing the desired output.
In mathematics, there is a collection of methods called root-finding algorithms that can provide solutions to such problems in some cases.
To keep it simple, the general approach is iterative and with each iteration, the algorithm tries to approximate a root value that solves the functional equation within a set error margin. If the root value is within the desired error margin - we accept the solution, if not - we iterate further.
In cases where the desired error margins are too small and/or functions too complex, it is possible that a solution can’t be reached by these methods. In our case though, it was perfect since we are working with money, and error rates smaller than 0.01 don’t make a difference for our final approximation.
The root-finding method that was chosen for our implementation is called Steffensen's method. The main benefits are:
1. The method doesn’t use derivatives
This means we can use our initial function as an argument for calculating each iteration. The general formula looks like this:
The downside is that we need to compute the function twice for each iteration, but this is negligible because of our large error margin and because of the next benefit.
2. The method has quadratic convergence
We can think of convergence as “how quickly are we moving towards our desired root approximation with each iteration”, and since this method has quadratic convergence - the number of correct digits in the answer doubles with each step. In our case, it usually takes up to 3 iterations until we approximate a correct solution.
Important to note is that the initial X value we choose plays a role in how quickly we arrive at a solution. In this case, the most effective approach is to start with the initial result we get from our function for the desired remuneration since adjusting for any payment, regardless of type (unless unrealistically large), shouldn’t throw us off by much.
We can take for granted that an example function:
takes the desired net salary as an argument
takes the desired bonus of any remuneration type
returns a list of all remunerations
Let’s say a client wants to sign an employee with a net salary of 2000 leva. This means our function yields the following with this input parameter:
BR - 2546,82 leva (base remuneration)
GR - 2577,38 leva (gross remuneration)
B - 3065,02 leva (total budget cost for the employer)
NR - 2000 leva (net salary that the employee receives)
Let’s say that after some months, the employer decides to give his employee a bonus. The budget that the employer can afford is 300 leva, so our parameters now become:
2000 leva net salary and 300 leva as budget bonus
The final result is as follows:
BR - 2546,82 leva (the same base remuneration, which is important)
GR - 2829,65 leva (gross remuneration has increased by 252,27 leva)
B - 3365,02 leva (the total budget has risen exactly by 300 leva)
NR - 2195,75 leva (net salary is now 195,75 leva higher)
The way we managed to get the exact net equivalent with a 300 leva budget bonus is by using our root-finding method with a start iteration value of 2000 to approximate for which net remuneration does our budget equal 3065,02 leva + 300 leva bonus. In this scenario, after a single iteration, we get a correct answer of 2195,75 leva.
This core principle can be used to mix and match any desired remuneration type with any desired bonus type. Our final implementation has in total 16 input parameters and can be accessed on balans.bg.