# Rating Engine

The Rating engine's main responsibility is calculating the premium, limits, and deductibles on coverages and fees (Items). It also provides some helper API endpoints to compile calculations, to get reserved names, and to get utility references.

# Compilation

# API details

  • API Endpoint: /rating/compile-calculation/
  • Parameters:
    • calculation (string): calculation code
  • Returns: JSON containing calculation code and references

# Description

To compile calculations the rating engine uses RestrictedPython's compile_restricted_eval function with a custom ast.NodeTransformer called RateCompiler.

The RateCompiler takes care of extracting all referenced names on the calculation, as well as transforming all number literals to Decimals.

For example, this calculation:

mileage * 42
1

Gets compiled into this:

{
    "calculation": "mileage * 42",
    "code": "gANjZGlsbC5kaWxsCl9sb2FkX3R5cGUKcQBYCAAAAENvZGVUeXBlcQGFcQJScQMoSwBLAEsASwRLQEMSZQBlAWUCZACDAmQBgwEUAFMAcQRYBwAAAERlY2ltYWxxBVgCAAAANDJxBoZxB1gHAAAAbWlsZWFnZXEIWAkAAABfZ2V0YXR0cl9xCVgHAAAAZGVjaW1hbHEKh3ELKVgIAAAAPHN0cmluZz5xDFgIAAAAPG1vZHVsZT5xDUsBQwBxDikpdHEPUnEQLg==",
    "references": {
        "current": [
            "mileage",
            "decimal"
        ]
    },
    "errors": []
}
1
2
3
4
5
6
7
8
9
10
11

This API is used by BriteLines to compile calculations, compiled code is saved on the database and whenever a Risk needs to be rated the compiled code is used directly, which speeds up rating.

# Reserved Names

# API Details

  • API Endpoint: /rating/reserved-names/
  • Returns: List of reserved names

# Description

Reserved names are all the built in references that are used by the Rating Engine and that cannot be used to name a field, rate table, calculation, or item.

Some examples are:

bc
None
False
True
bool
str
decimal
ROUND_UP
ROUND_DOWN
items
field_answers
1
2
3
4
5
6
7
8
9
10
11

They are a combination of the safe_builtins defined on RestrictedPython, bc that includes all the RatingEngineGlobals (bc.optional, bc.max, bc.min), and ChildRiskQuerySet lookup arguments (items, field_answers, total_premium, calculations and rate_tables).

# Utilities References

# API Details

  • API Endpoint: /rating/utilities-references/
  • Returns: List of utilities

# Description

Returns all the utilities available on the RatingEngine, along with a label, type, display and doc. This are mostly used for autocomplete purposes on the UI and for showing documentation.

Example result:

[
  {
    "name": "optional",
    "label": "optional",
    "type": "Utility",
    "display": "Utility",
    "doc": "Marks a reference as optional. If the reference can not be resolved then the\n        default value is used instead.\n\n        ### Examples\n\n        ```python\n        optional(myOptionalField, default=0.0)\n        ```"
  },
  {
    "name": "bc.round",
    "label": "bc.round",
    "type": "Utility",
    "display": "Utility",
    "doc": "Rounds a number to a given decimal place using a given rounding method.\n\n        ### Parameters\n\n        * `value` (number)\n            * The number to round\n        * `round_to`\n            * The digit that the value should be rounded to\n        * `round_method`\n            * The method to use when rounding\n\n        ### Examples\n\n        ```python\n        round(numberField, 2)\n        ```\n\n        ```python\n        round(numberField, round_to=NEAREST_HUNDRED, round_method=ROUND_UP)\n        ```"
  }
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# Computed Fields Evaluation

# API Details

  • API Endpoint: /rating/evaluate-computed-fields/
  • Parameters:
    • unified_risk_state
    • risk_state_id ID of the Risk we are currently rating
    • product and version (needed to lookup the Risk Type State, either on the cache or on the lines API)
    • rating_date
    • policy_inception_date
  • Returns: risk_state with computed fields evaluated and added to field_answers

# Description

This API endpoint takes care of evaluating all the computed fields to a value so that they can be used in rating.

When calling evaluate-computed-fields endpoint, the RatingEngine will be initialized and the method evaluate_computed_fields will be called. This method is going to evaluate this field's calculation, and include its value on the field_answers key on the risk state.

# Example

For example, if we had:

driverAge = bc.age(dateOfBirth)
1

Given this values under field_answers:

"field_answers": {
  "dateOfBirth": "1990-02-02"
}
1
2
3

The endpoint will return a risk_state with driverAge now included under field_answers:

"field_answers": {
  "dateOfBirth": "1990-02-02",
  "driverAge": 19
}
1
2
3
4

# Rating

# API Details

  • API Endpoint: /rating/rate/
  • Parameters:
    • unified_risk_state
    • risk_state_id of the Risk we are currently rating
    • product and version (needed to lookup the Risk Type State, either on the cache or on the lines API)
    • rating_date
    • policy_inception_date
  • Returns: Rated risk_state

# Description

Rating is performed by taking the details about a Risk Type (risk_type_state) and details about a Quote (risk_state) and combining them to determine each Item's premium, limits, and deductible.

In order to rate a risk the RatingEngine class is initialized and the method rate_all_items is called. This method takes care of evaluating all the calculations in order, making sure that all dependencies are resolved before evaluating a calculation.

Calculations and rate tables can reference other entities. The Rating Engine uses the toposort algorithm to determine the order in which references need to be resolved. For more on the topological sorting algorithm read here.

It finally returns a rated Risk State, which is a Risk State with the values for total_premium and premium (on each item) filled out.

# Toposort

The Rating Engine uses the toposort_flatten utility from the toposort library, to get an ordered list of references that need to be resolved for a calculation to be evaluated.

# Example

Given this calculations:

calc1 = calc2 + calc3
calc2 = calc3 * 2
calc3 = field
1
2
3

And this references:

references = {'calc1': {'calc2', 'calc3'}, 'calc2': {'calc3',}}
1

The toposort_flatten utility will return this ordered list of references:

['calc3', 'calc2', 'calc1']
1