【问题标题】:Getting the maximum value without using a for loop for an equation Python在不使用 for 循环的情况下获取最大值 Python
【发布时间】:2021-11-06 02:00:35
【问题描述】:

下面的代码遍历下面的r_pnl 函数并计算从$100 开始的复利值,并使用r_pnl 值作为利率。唯一的区别是利息金额不一样,可能有正负利息金额。此函数使用Compounding 函数计算。还有另一个因素是杠杆,因此借入的金额可以从无杠杆开始到初始借入金额的 9.75 倍1 - 9.75,费用为-0.15 乘以r_pnllev_iter。有没有一种方法可以在 1 - 9.75 之间找到杠杆金额的最大值,而无需 for 循环并为每个杠杆值计算 Compounding?我正在尝试尽可能降低预期输出和运行时间。

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)

预期输出:

Max value: 110.508 lev: 5.75 

运行时:

Wall time: 2.45 ms

打印结果:

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

【问题讨论】:

  • r_pnl 在杠杆变量上是单峰的吗,正如您的示例所暗示的那样?如果是这样,您可以使用二进制搜索来查找局部最大值,这也是全局最大值。如果你能把函数写成方程,你也可以只用微积分来求最大值。

标签: python arrays numpy for-loop math


【解决方案1】:

您可以广播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()]}'

输出

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

【讨论】:

    猜你喜欢
    • 2021-11-25
    • 2016-05-14
    • 2019-12-01
    • 2018-05-31
    • 2013-05-19
    • 1970-01-01
    • 2015-04-24
    • 2019-09-02
    • 1970-01-01
    相关资源
    最近更新 更多