# Banking: Calculate the Capital Requirement to calculate Risk-Weighted Assets

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.'''
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


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)


(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.