Rate strategies, what each row works on, the carry-forward rule, gated extensions, proration, currency, tax, commission and rounding, with numbers.
The BimaStack team · · 7 min read
Behind every rate card is the same small set of rules: how a rate turns an amount into a premium, which amount each line works on, the order lines are applied in, and how the result is prorated, converted, taxed and rounded. BimaStack carries these rules forward from the systems insurers already trust, and runs them as ordinary workflows and blocks. This post explains each one, with numbers.
A premium is many small rows
A premium isn’t one big formula. It is a list of rate rows, each worked out by the strategy that row declares and folded into a running total, in a strict order:
The shape of every premium
for each group of rows (a section, a cover type or a binder), in strict order:
for each row:
choose the amount it works on (the sum insured, or the total so far)
work out its contribution with the row's strategy
add it to, or take it from, the running total
emit the group's total, rounded
Tax and commission are two more passes of the same shape, run on the premium once it is known.
Rate strategies
Strategy
Rule
Example
Fixed
A flat amount, or a flat percentage of the amount
A policy fee of KES 500, whatever the sum insured
Absolute range
Once the amount falls in a band, the band’s rate applies to all of it
0–1,000,000 at 2%: 800,000 gives 16,000
Absolute range, age-banded
The same, with an age band
Personal accident by age of the insured
Absolute range, special banded
The same, on another count (members, headcount)
A scheme rated by number of lives
Recurring (tiered) range
Each band’s rate applies only to the part of the amount inside it, like income-tax brackets
0–100,000 at 1% and 100,000–500,000 at 0.5%: 300,000 gives 1,000 + 1,000 = 2,000
Step range
The band’s width is what is charged, once the amount reaches it
A band of 50 seats at a per-seat rate: 50 × rate
A tiered range is configured as one rate row per band, each using the same step formula, max(min(amount, bandTo) − bandFrom, 0) × rate, and summed. One row, one band, one mental model, for every strategy.
One row, in order
Besides its rate, every row may carry a multiplier and divisor, a free limit, a minimum and a proration type. They are applied in a fixed order:
1
Convert the currency
If the row’s rate is in another currency, at the published rate for the pair, the same rate for the whole calculation.
2
Take off the free limit
The strategy never sees the excluded part. A benefit rated at 10% with an 80,000 free limit, on a value of 90,000: 10% of 10,000 is 1,000.
3
Apply the strategy
With the multiplier and divisor.
4
Apply the minimum
The row’s contribution is at least its minimum: max(result, minimum).
5
Prorate
Full term, prorated by days, or by a short-period scale.
What each row works on: its role
Roles
Work on
Effect
Sum insured, section limit, extension limit, extension sum insured, medical limit, occupation limit
Each role has a default amount to work on, and any row may override it. Excess protector shows why: the general rule says the running total, but real schemes charge it on the vehicle’s value (0.25% of the value). Both are the same setting on the row.
The carry-forward rule
The single most important rule, and the easiest to get wrong: loadings and discounts work on the total built by every earlier row in the group, not on the sum insured.
Row
Works on
Contribution
Total
Base premium
Sum insured
10,000
10,000
Loading +10%
10,000
+1,000
11,000
Discount −5%
11,000
−550
10,450
Because order changes the answer, rows within a group must have one unambiguous order. A group whose order can’t be decided is refused, never computed in whatever order the data arrived. In a workflow this is the aggregate chain: each step names the total it builds on.
Optional rows are gated
A no-claim discount applies only when the quote says the policy is eligible, at a level that matches the row. An excess protector applies only when the client opted in. The same goes for any optional extension (terrorism, road rescue, loss of use): the row is in the table, but contributes only when its eligibility flag is set, and shows as zero otherwise.
A percentage from a day-band scale: short covers aren’t charged proportionally less, because the risk doesn’t fall in proportion
Proration is applied per row, before the row joins the running total, so later loadings work on prorated amounts.
Tax and commission
Tax is a second pass over the finished premium: each tax row (a training levy, a policyholders’ compensation fund levy, stamp duty) is rated with the same strategies, without roles.
Commission is a third pass, worked out on premium and tax, owed to whoever placed the business. It can be worked out with the quote or later, per distributor type.
The client pays premium plus tax. Commission is never part of the client’s total.
Rounding
No floating point, anywhere money or rates are handled.
Ten decimal places carried through every intermediate step.
Half to even for division and final rounding: it avoids the upward drift that rounding half up adds over many quotes.
Round only at the edges: a group’s total, the tax total, the commission total, an amount shown or stored. A running total is never rounded part way.
Fail closed
A calculation stops with a clear error, never a best guess, when rows can’t be put in order, a rate or formula has no version in effect on the date, a formula fails as it runs, or an outside call fails.
How BimaStack runs these rules
None of this is fixed code. Each rule above is configured in a product’s pricing workflow, from pieces you author: