5
\$\begingroup\$

I know it's not the perfect code, but it outputs the correct values. Could anyone give me some pointers on how to make the operation more Pythonic?

def capital_requirement(r, lgd, pd, madj, tenor):
    '''Returns the capital requirement.'''
    madjcoeff = 1.5
    tsub = 2.5
    a1 = (stat.norm.ppf(pd) + r**0.5 * stat.norm.ppf(0.999)) / ((1 - r)**0.5)
    b1 = lgd * stat.norm.cdf(a1) - lgd * pd
    return b1 * (1 + ((tenor - tsub) * madj)) / (1- madjcoeff * madj)

See: https://en.wikipedia.org/wiki/Capital_requirement

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

The function name is very nice. The docstring adds nothing to that. Consider describing one or more arguments, especially if there are tricky details about their validity. Definitely add a URL describing the math approach.

Sorry, I didn't notice how the wikipedia page on Capital_requirement relates to the details of the formula.

Overall the code is clear. If you really wanted to delete the b1 temp variable for some reason you might write this two-liner:

return ((lgd * stat.norm.cdf(a1) - lgd * pd)
        * (1 + ((tenor - tsub) * madj)) / (1- madjcoeff * madj))

(I suppose lgd could be factored out, if desired.) In any event, the a1 temp definitely helps with readability, you'll want to hang on to that. Something to keep in mind is that subexpressions can raise exceptions. If you're concerned that might happen, it may be useful to break out several temp variables, each on its own line, so the stack trace will pinpoint where things went south.

tsub is a perfectly nice concise name to choose, but please add a comment:

tsub = 2.5  # tenor subtrahend

Not sure how "constant" these two are, but you might allow callers to change them:

def capital_requirement(r, lgd, pd, madj, tenor, madjcoeff=1.5, tsub=2.5):

It's pretty clear that stat.norm.ppf(0.999) is not implementing the .99 given in your formula.

You might validate r:

assert 0 < r < 1

If out-of-range values sneak in, be aware that math.sqrt() will raise ValueError, which you probably want, while ** 0.5 will return an imaginary root.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.