# # 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
```

Gets compiled into this:

```
{
"calculation": "mileage * 42",
"code": "gANjZGlsbC5kaWxsCl9sb2FkX3R5cGUKcQBYCAAAAENvZGVUeXBlcQGFcQJScQMoSwBLAEsASwRLQEMSZQBlAWUCZACDAmQBgwEUAFMAcQRYBwAAAERlY2ltYWxxBVgCAAAANDJxBoZxB1gHAAAAbWlsZWFnZXEIWAkAAABfZ2V0YXR0cl9xCVgHAAAAZGVjaW1hbHEKh3ELKVgIAAAAPHN0cmluZz5xDFgIAAAAPG1vZHVsZT5xDUsBQwBxDikpdHEPUnEQLg==",
"references": {
"current": [
"mileage",
"decimal"
]
},
"errors": []
}
```

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
```

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 ```"
}
]
```

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)
```

Given this values under `field_answers`

:

```
"field_answers": {
"dateOfBirth": "1990-02-02"
}
```

2

3

The endpoint will return a risk_state with `driverAge`

now included under `field_answers`

:

```
"field_answers": {
"dateOfBirth": "1990-02-02",
"driverAge": 19
}
```

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
```

2

3

And this references:

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

The `toposort_flatten`

utility will return this ordered list of references:

```
['calc3', 'calc2', 'calc1']
```