Rating slice details for PersonalAutoCovCostData
The PASysTableRatingEngine class implements the rateSlice method by using the following general algorithm. The structure is similar to other lines of business.
- If the slice is canceled, do nothing.
- Otherwise, loop across the line-level coverages. Within that loop, loop over each vehicle and rate the combination of that line-level coverage and the vehicle.
- Loop over each vehicle. Within that loop, loop over each coverage on the vehicle and rate the coverage.
Since the argument passed to the rateSlice method is already sliced as of the appropriate effective date, the slice rating code is simple. It does not need complex code to determine effective dates. It can just traverse the graph in the normal straightforward way.
Look at the standard collision coverage to see more details of rating a coverage. The rateSlice
method calls to rateVehicleCoverage for each coverage on a vehicle.
private function rateVehicleCoverage(cov : PersonalVehicleCov) : PersonalVehicleCovCostData {
assertSliceMode(cov)
switch (typeof cov) {
case PACollisionCov: return ratePACollisionCov(cov)
case PAComprehensiveCov: return ratePAComprehensiveCov(cov)
case PARentalCov: return ratePARentalCov(cov)
case PATowingLaborCov: return ratePATowingLaborCov(cov)
default:
PCFinancialsLogger.logDebug("Not rating ${(typeof cov)}")
return null
}
}
The switch
statement using the type of the coverage is a fairly standard pattern
in the built-in rating code, within the rateSlice method of a line-specific
rating engine.
Let us now look at the rating code for the personal auto collision coverage.
private function ratePACollisionCov(cov : PACollisionCov) : PersonalVehicleCovCostData {
var ratingDate = ReferenceDatePlugin.getCoverageReferenceDate(
cov.Pattern as CoveragePattern, cov.PersonalVehicle)
var baseRate = getRateFactor("papCollRate", "base", ratingDate)
var adjRate = baseRate
* getRateFactor("papCollDeductible", cov.PACollDeductibleTerm.OptionValue.OptionCode, ratingDate)
* getAgeFactor(cov.PersonalVehicle, ratingDate)
* getRateFactorInRange("papVehicleCostNew", cov.PersonalVehicle.CostNew as double, cov, ratingDate)
* getDriverRatingFactor(cov.PersonalVehicle, ratingDate)
* getNoLossDiscountFactor(cov.PersonalVehicle.PALine, ratingDate)
* getUWCompanyRateFactor(cov.PersonalVehicle.PALine)
return rateVehicleCoverage_impl(cov, baseRate, adjRate)
}
The structure in this example is typical. First, figure out the date on which to look up rates. Next, look up a base rate factor in the demonstration system tables used for personal auto rating. Multiply those factors by various modifiers, such as the following items.
- Chosen deductible
- Vehicle age
- Vehicle cost
- Diver’s record
- Loss history
- Underwriting company
In this example, the last line of the method calls
out to the common rateVehicleCoverage_impl
function. That function sets the effective date span of the cost to be
one of the following dates.
- Start date = the start of the slice to rate
- End date = the start of the next slice date
The implementation is shown below.
private function rateVehicleCoverage_impl(cov : PersonalVehicleCov, baseRate : BigDecimal,
adjRate : BigDecimal) : PersonalVehicleCovCostData {
var start = cov.SliceDate
var end = getNextSliceDateAfter(start)
var cost = new PersonalVehicleCovCostData(start, end, cov. Currency, RateCache, cov.FixedId)
populateCostData(cost, baseRate, adjRate)
return cost
}
The method calls a standard populateCostData method that is common to both vehicle-level and line-level coverage costs. The method copies the rates into the cost, sets the term amount, and copies the standard columns into the actual columns.
private function populateCostData(cost : CostData, baseRate : BigDecimal, adjRate : BigDecimal) {
cost.NumDaysInRatedTerm = this.NumDaysInCoverageRatedTerm
cost.StandardBaseRate = baseRate
cost.StandardAdjRate = adjRate
cost.Basis = 1 // Assumes 1 vehicle year
cost.StandardTermAmount = adjRate.setScale(RoundingLevel, this.RoundingMode)
cost.copyStandardColumnsToActualColumns()
}
The NumDaysInCoverageRatedTerm method is abstract in the superclass
AbstractRatingEngine, so you must implement this method in your rating engine. The method
returns the number of days in a standard coverage term.
The result of the rateVehicleCoverage call is a fully-populated
PersonalVehicleCovCostData object. Other code can now add this object to the list of
CostData objects.
The AbstractRatingEngine class might later merge this CostData with other
adjacent CostData objects. Next, the AbstractRatingEngine prorates the cost.
Lastly, the AbstractRatingEngine built-in methods convert the cost data object to a cost entity
instance and persist that object to the database.
