mages / ChainLadder

Claims reserving models in R
https://mages.github.io/ChainLadder/
75 stars 62 forks source link

Cashflow projection #8

Closed ojessen closed 8 years ago

ojessen commented 8 years ago

Hi,

is there a build-in method to calculate the cashflow projection from the complete triangle? Currently I am running the following code, which might be usefull for others as well

triang2cashflow <- function(matj) {
  cf = rep(0, nrow(mat)-1)

  for(i in 1:length(cf)){
    idx_row = nrow(mat):(1+i)
    idx_col = (1+i):nrow(mat)
    tmp = 0
    for(j in seq_along(idx_col)){
      tmp = tmp + mat[idx_row[j], idx_col[j]]
    }
    cf[i] = tmp
  }

  cf
}
chiefmurph commented 8 years ago

By "projection from the complete triangle", I assume you mean sums along the diagonals of the incremental paid losses, beginning with the diagonal "marked" by the cell in the last row, second column, where each diagonal corresponds to the first, second, third, ... subsequent calendar period. Your solution does seem to work -- other than the typo in the argument name -- but I've always thought such for-loops aggravatingly obscure what's going on and it takes me an inordinate amount of time to understand what they're actually doing to confirm that, yes, it does work.

Alternatively, it is possible to vectorize an approach using R's 'row' and 'col' functions that -- to me -- illuminates the thought process. To wit:

diag = row(mat) + col(mat) - 1

is an "indicator" matrix identifying the diagonals of 'mat' starting in the upper left corner and ending in the lower right. The diagonals that you want to sum are those that are larger numerically than the last row of mat:

use <- unique(diag[diag > nrow(mat)])

Now simply sum the cells of mat whose diagonals are those you want to use:

sapply(use, function(i) sum(mat[diag == i]))

I personally enjoy having "names" available whenever possible, in this case identifying the calendar period of the cash flow, so I would add them as per the last line of the version below:

triang2cashflow <- function(mat) { diagmat <- row(mat) + col(mat) - 1 use <- unique(diagmat[diagmat > nrow(mat)]) structure(sapply(use, function(i) sum(mat[diag == i])), names = use) }

Obviously, this approach relies on the assumption that the matrix is somewhat "regular", e.g., a one-to-one correspondence between calendar period and origin period. I don't think it would be too hard to work out a more general vectorized solution using the "long version" of a "triangle object", but that might require a more precise definition of the objective, so I leave that for another!

Thank you for your interest in making ChainLadder more useful.

Dan

ojessen commented 8 years ago

Thanks, Dan, for this more "R-like" solution (which has a small typo in structure..., it should be mat(diagmat == i)).

As I suppose the input would be the complete triangle from one of the ChainLadder-Methods, I suppose the assumptions about being regular should be fulfilled.

Talking a bit more about the use case: We are using MackChainladder and BootChainladder for the calculation of the best estimates under Solvency II, and need the discounted cashflows for this, and so need the undiscounted cashflows on an annual basis.

chiefmurph commented 8 years ago

Yes, thanks for the heads-up on the typo, Owe!

It would be a good exercise to see how "regular" are the projected, complete triangles from the various ChainLadder methods.

Back to your use case, to you also discount the cash flows from stressed scenarios at higher confidence levels?

ojessen commented 8 years ago

I think this issue can be closed: As i found out, one can get the Claims development result not only for 1 year ahead, but for all the years of the development with CDR(tri, dev = "all")