> ## Documentation Index
> Fetch the complete documentation index at: https://docs.canary.effectiveai.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Rate a book against a market

> Rate every submission with every program in a market, compare the premiums policy by policy, and find the submissions that only one program rates.

Rate the example book with the current and the proposed program from
[Create a market](/relativities/how-to/create-a-market):

```python theme={null}
from decimal import Decimal

from relativities import Market, Program

current = Program.load("effective://example-ca-ppa")
book = current.example_book
rates = current.rater.tables["BaseRate"]
collision = rates["coverage"] == "collision"
rates.loc[collision, "rate"] = rates.loc[collision, "rate"] * Decimal("1.05")
market = Market({"current": current, "proposed": current.with_rater(current.rater.with_tables({"BaseRate": rates}))})

results = market.rate(book)
results[["submission_id", "program", "status", "premium"]].head(4)
#   submission_id   program     status premium
# 0       S000001   current  succeeded    2636
# 1       S000001  proposed  succeeded    2694
# 2       S000002   current  succeeded    5339
# 3       S000002  proposed  succeeded    5461
```

`market.rate` returns one row per submission and program, keyed by `submission_id` and `program`.

## Compare premiums policy by policy

Pivot the premiums to one row per submission, and compare the programs:

```python theme={null}
premiums = results.pivot(index="submission_id", columns="program", values="premium").astype(float)
change = premiums["proposed"] / premiums["current"] - 1
change.describe()[["count", "mean", "min", "max"]].round(4)
# count    96671.0000
# mean         0.0163
# min          0.0000
# max          0.0355
```

The 96,671 policies that both programs rate change by 0% to 3.55%, and by 1.63% on average.
A policy with liability coverage alone keeps its premium.

## Find the overall change

Sum the premiums of the submissions that both programs rate. The proposed program raises the total by 1.81%:

```python theme={null}
matched = premiums.dropna()
round(float(matched["proposed"].sum() / matched["current"].sum() - 1), 4)  # 0.0181
```

## Count the unrated submissions by program

```python theme={null}
results.query("status != 'succeeded'").groupby(["status", "program"]).size().unstack()
# program         current  proposed
# status
# invalid_inputs      394       394
# refused            2935      2935
```

Report these submissions beside the comparison, with their reasons.

## Explain one submission in each program

`market.explain` puts each program's steps side by side, keyed by `program`:

```python theme={null}
steps = market.explain(book, "S000001").query("kind == 'calculation'")
steps.pivot(index="name", columns="program", values="value").query("current != proposed")
# program                                current proposed
# name
# base_rate.collision                       1519  1594.95
# premium                                   2636     2694
# vehicles[0].coverage_premium.collision     562      590
# vehicles[0].premium                       1265     1293
# vehicles[1].coverage_premium.collision     611      641
# vehicles[1].premium                       1371     1401
```

The rows that differ trace S000001's \$58 increase to the collision base rate.

```python theme={null}
market.close()
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.