Python优化最小化如何?

时间:2017-08-02 12:51:28

标签: optimization

我是Python的初学者,我正在尝试使用相同的Excel Solver Logic最小化此功能,但我无法这样做。你能帮我吗?

我想要最小化的功能如下:

from datetime import date
import numpy as np
def nelsonsiegel(Beta0,Beta1,Beta2,Beta3,Lambda1,Lambda2):
    SettleDate = date(2017,07,14)
    Bond1MaturityDate = date(2018,7,13)
    Bond3MaturityDate = date(2020,2,17)
    Bond5MaturityDate = date(2022,7,21)
    Bond10MaturityDate = date(2027,1,20)
    Bond15MaturityDate = date(2031,9,16)
    Bond20MaturityDate = date(2037,3,17)
    Yearfraction = [float((Bond1MaturityDate-SettleDate).days)/365,float((Bond3MaturityDate-SettleDate).days)/365, float((Bond5MaturityDate-SettleDate).days)/365, float((Bond10MaturityDate-SettleDate).days)/365, float((Bond15MaturityDate-SettleDate).days)/365, float((Bond20MaturityDate-SettleDate).days)/365]
    CouponRate = [0,0.0290,0.0321,0.0494,0.0585,0.0624]
    BondPrices = [0.97863,0.99745,0.9968, 0.99922,0.98724,0.96679 ]
    NS = []      
    df = []
    rst = []
    NSS = []
    NegM = []
    for i in range(len(Yearfraction)):        
      NelsonSiegel = Beta0 + (Beta1 * ((1-np.exp(-Yearfraction[i]/Lambda1)/Yearfraction[i]*Lambda1))) +  (Beta2 * ((((1-np.exp(-Yearfraction[i]/Lambda1))/(Yearfraction[i]*Lambda1))) - (np.exp(-Yearfraction[i]/Lambda1)))) + (Beta3 * ((((1-np.exp(-Yearfraction[i]/Lambda2))/(Yearfraction[i]*Lambda2))) - (np.exp(-Yearfraction[i]/Lambda2)))) 
      NS.append(NelsonSiegel)
      discountfactor = np.exp(-Yearfraction[i]*NS[i])  
      df.append(discountfactor)
      if i < 6: 
          result = (1 + CouponRate[i])* df[i]
          m = Yearfraction[i] - 1
          if m < 0:
              rst.append(result)                  
          while m > 0:
              NelsonSiegelCpnRe = Beta0 + (Beta1 * ((1-np.exp(-m/Lambda1)/m*Lambda1))) +  (Beta2 * ((((1-np.exp(-m/Lambda1))/(m*Lambda1))) - (np.exp(-m/Lambda1)))) + (Beta3 * ((((1-np.exp(-m/Lambda2))/(m*Lambda2))) - (np.exp(-m/Lambda2))))                            
              result  = result + (CouponRate[i] * np.exp(-m*NelsonSiegelCpnRe))
              NSS.append(NelsonSiegelCpnRe)   
              m = m -1
              if m <0:
                   rst.append(result)
                   a = np.array(rst)     
    Spread = (BondPrices - a )**2
    #SpreadtoMinimize = sum(Spread)             

    return sum(Spread) 

通常会返回一笔金额。应该通过在Beta0,Beta1,Beta2,BEta3,Lambda1,Lambda2上播放来最小化这个总和。 Beta0到Beta3的约束应该是这些变量可以在-1和1之间振荡.Lambda1和Lambda2没有约束。

您知道如何编写代码来执行该任务吗? 谢谢 SB

P.S:我用这些参数执行函数:nelsonsiegel(0.01,0.01,0.01,0.01,1,1)

1 个答案:

答案 0 :(得分:0)

好吧,我会重写这个等式,所以它只需要一个参数,然后根据需要将其解析为函数内部的变量。在通过

调用优化引擎之后
  

scipy.optimize.minimize

因此,产生的代码将像:

from datetime import date
import numpy as np
from scipy.optimize import minimize

def nelsonsiegel(x):
    Beta0, Beta1, Beta2, Beta3, Lambda1, Lambda2 = x
    SettleDate = date(2017,07,14)
    Bond1MaturityDate = date(2018,7,13)
    Bond3MaturityDate = date(2020,2,17)
    Bond5MaturityDate = date(2022,7,21)
    Bond10MaturityDate = date(2027,1,20)
    Bond15MaturityDate = date(2031,9,16)
    Bond20MaturityDate = date(2037,3,17)
    Yearfraction = [float((Bond1MaturityDate-SettleDate).days)/365,float((Bond3MaturityDate-SettleDate).days)/365, float((Bond5MaturityDate-SettleDate).days)/365, float((Bond10MaturityDate-SettleDate).days)/365, float((Bond15MaturityDate-SettleDate).days)/365, float((Bond20MaturityDate-SettleDate).days)/365]
    CouponRate = [0,0.0290,0.0321,0.0494,0.0585,0.0624]
    BondPrices = [0.97863,0.99745,0.9968, 0.99922,0.98724,0.96679 ]
    NS = []      
    df = []
    rst = []
    NSS = []
    NegM = []
    for i in range(len(Yearfraction)):        
      NelsonSiegel = Beta0 + (Beta1 * ((1-np.exp(-Yearfraction[i]/Lambda1)/Yearfraction[i]*Lambda1))) +  (Beta2 * ((((1-np.exp(-Yearfraction[i]/Lambda1))/(Yearfraction[i]*Lambda1))) - (np.exp(-Yearfraction[i]/Lambda1)))) + (Beta3 * ((((1-np.exp(-Yearfraction[i]/Lambda2))/(Yearfraction[i]*Lambda2))) - (np.exp(-Yearfraction[i]/Lambda2)))) 
      NS.append(NelsonSiegel)
      discountfactor = np.exp(-Yearfraction[i]*NS[i])  
      df.append(discountfactor)
      if i < 6: 
          result = (1 + CouponRate[i])* df[i]
          m = Yearfraction[i] - 1
          if m < 0:
              rst.append(result)                  
          while m > 0:
              NelsonSiegelCpnRe = Beta0 + (Beta1 * ((1-np.exp(-m/Lambda1)/m*Lambda1))) +  (Beta2 * ((((1-np.exp(-m/Lambda1))/(m*Lambda1))) - (np.exp(-m/Lambda1)))) + (Beta3 * ((((1-np.exp(-m/Lambda2))/(m*Lambda2))) - (np.exp(-m/Lambda2))))                            
              result  = result + (CouponRate[i] * np.exp(-m*NelsonSiegelCpnRe))
              NSS.append(NelsonSiegelCpnRe)   
              m = m -1
              if m <0:
                   rst.append(result)
                   a = np.array(rst)     
    Spread = (BondPrices - a )**2
    #SpreadtoMinimize = sum(Spread)             

    return sum(Spread)
x_0 = [0.01, 0.01, 0.01, 0.01, 1, 1]  # Here you have to define an intial guess
bnds = zip([-1,-1,-1,-1, -np.inf, -np.inf],[1,1,1,1,np.inf, np.inf])
result = minimize(nelsonsiegel, x_0, bounds=bnds)

我希望它能做到

此致