Getting the maximum value without using a for loop for an equation Python

The code below iterates through the r_pnl function below and calculates the compounding value that starts form $100 and uses the r_pnl values for the interest rates. The only difference is that the interest amount are not the same and there could be positive and negative interest amounts. This function is calculated with the Compounding function. There is also another factor that is leverage, so the amount of money borrowed could start with no leverage to 9.75 times initial amount borrowed 1 - 9.75 there is a fee of -0.15 that is multiplied by r_pnl and lev_iter. Is there a way to find the maximum value for the leverage amount between 1 - 9.75 without the need of a for loop and calculating Compounding for each Leverage value? I am trying to get the Expected output and the runtime lowered as much as possible.

import numpy as np

Amount = 100
Leverages = np.arange(start=1, stop=10, step=0.25)
r_pnl = np.array([0.0, -0.39247204114412626, 0.3122849117324323, 0.6134640190523772, 9.04025334826345, 0.3480324252545822, 0.6701565095475336, -1.0390576755639311, 0.0, -0.5423604436038103, -0.4251610104101389, -0.1218472666501971, -0.1927069235919652, 3.1356759237117817, -0.8274178347269903, -0.6014871237753395, -0.08516044803648884, -0.35584520733480385, 0.17304075235109945, -0.3252022308194671, -0.19104483630759042, -0.17181374182909762, 0.463788348215472, -0.16367088607595306, -0.12805769442898776, -0.21855930668834814, 0.48122377032225083, 1.3597313947097627, 0.4480022947379504, 0.0, -0.8100583722249745, -0.5125916528667578, -0.04964580114966066, -0.5841192117035439, -0.0971651097446353])

def func(PnL_val):
    for lev_iter in Leverages:
        PnL2 = (PnL_val-0.15)*lev_iter
        Compounding = Amount * np.cumprod(PnL2 / 100 + 1)
        print("result: ",np.around(Compounding[-1],2),"lev: ",lev_iter)
        
func(r_pnl)

Expected Output:

Max value: 110.508 lev: 5.75 

Runtime:

Wall time: 2.45 ms

print Results:

Compounding:  103.55655488289916 lev iter 1.0
Compounding:  104.32201041415827 lev iter 1.25
Compounding:  105.0392189936324 lev iter 1.5
Compounding:  105.70881856813112 lev iter 1.75
Compounding:  106.33145989067727 lev iter 2.0
Compounding:  106.90780570095535 lev iter 2.25
Compounding:  107.43852992445258 lev iter 2.5
Compounding:  107.92431689016875 lev iter 2.75
Compounding:  108.36586056676578 lev iter 3.0
Compounding:  108.76386381702079 lev iter 3.25
Compounding:  109.11903767044109 lev iter 3.5
Compounding:  109.43210061389581 lev iter 3.75
Compounding:  109.70377790010848 lev iter 4.0
Compounding:  109.93480087385666 lev iter 4.25
Compounding:  110.12590631571297 lev iter 4.5
Compounding:  110.27783580316388 lev iter 4.75
Compounding:  110.39133508893116 lev iter 5.0
Compounding:  110.46715349632343 lev iter 5.25
Compounding:  110.50604333143713 lev iter 5.5
Compounding:  110.5087593120221 lev iter 5.75
Compounding:  110.4760580128271 lev iter 6.0
Compounding:  110.40869732723395 lev iter 6.25
Compounding:  110.3074359449858 lev iter 6.5
Compounding:  110.17303284581423 lev iter 6.75
Compounding:  110.00624680876668 lev iter 7.0
Compounding:  109.80783593702861 lev iter 7.25
Compounding:  109.57855719804199 lev iter 7.5
Compounding:  109.31916597870695 lev iter 7.75
Compounding:  109.03041565546391 lev iter 8.0
Compounding:  108.71305717904063 lev iter 8.25
Compounding:  108.36783867365625 lev iter 8.5
Compounding:  107.99550505046489 lev iter 8.75
Compounding:  107.59679763502601 lev iter 9.0
Compounding:  107.17245380858374 lev iter 9.25
Compounding:  106.72320666293831 lev iter 9.5
Compounding:  106.2497846686893 lev iter 9.75

Answer

You can broadcast Leverages:

import numpy as np

Amount = 100
Leverages = np.arange(start=1, stop=10, step=0.25)
r_pnl = np.array([0.0, -0.39247204114412626, 0.3122849117324323, 0.6134640190523772, 9.04025334826345, 0.3480324252545822, 0.6701565095475336, -1.0390576755639311, 0.0, -0.5423604436038103, -0.4251610104101389, -0.1218472666501971, -0.1927069235919652, 3.1356759237117817, -0.8274178347269903, -0.6014871237753395, -0.08516044803648884, -0.35584520733480385, 0.17304075235109945, -0.3252022308194671, -0.19104483630759042, -0.17181374182909762, 0.463788348215472, -0.16367088607595306, -0.12805769442898776, -0.21855930668834814, 0.48122377032225083, 1.3597313947097627, 0.4480022947379504, 0.0, -0.8100583722249745, -0.5125916528667578, -0.04964580114966066, -0.5841192117035439, -0.0971651097446353])

f_x = (((r_pnl - 0.15)*Leverages[:, None] / 100 + 1).cumprod(1)*Amount)[:,-1]
f'Max value: {f_x.max():.3f}, lev: {Leverages[f_x.argmax()]}'

Output

Max value: 110.509, lev: 5.75 # %timeit 10000 loops, best of 5: 23.7 µs per loop