lewisfogden / heavylight

A lightweight actuarial modelling framework for Python
https://lewisfogden.github.io/heavylight/
MIT License
5 stars 2 forks source link

Functions using future periods cause RecursionError #1

Closed zchmielewska closed 11 months ago

zchmielewska commented 11 months ago

As stated in the README, the functions that use future periods cause recursion error. For example:

import heavylight

class MyModel(heavylight.Model):
    def test(self, t):
        if t == 1440:
            return 1
        return self.test(t+1)

model = MyModel(do_run=True, proj_len=1440)
model_cashflows = model.ToDataFrame()
print(model_cashflows)

results in:

RecursionError: maximum recursion depth exceeded while calling a Python object

If I change the line 141 in heavylight.py from:

for t in range(proj_len):

to

for t in range(proj_len, -1, -1):

then it works without any problems.

So maybe the package should check if the given function calls itself with argument t+... and if so, then use the for-loop backwards. To check the argument of the function, the ast package can be used.

lewisfogden commented 11 months ago

Hi, I thought about this (and might work), but I like to think of a projection as going forward in time only. (i.e. everything relating to time t+1 is based on time t and prior)

Main place I've seen reference to t+1 from t is in discounting (e.g. pv(0) = (pv(1) + cf(1)) / (1 + disc rate), which seems to be a bit of a workaround for older pr*phet style models where everything has to be recursively specified, and functions etc can't be called on cashflows easily.

I prefer to be explicit in doing discount after the projection is run using an npv() function or generating a discount factor (v(t)) and then summing the discounted cashflows.

Aside from discounting, is there anywhere else you've seen future time periods used?

zchmielewska commented 11 months ago

Oh, I see your point. No, I see the reference to t+1 also only in case of discounting. Indeed, that's not the only way to discount and the discount function can be applied to cash flows.