2017-08-02 68 views
0

我是一名Python初学者,我试图使用相同的Excel求解器逻辑来尽量减少此功能,但我无法做到这一点。你能帮我么?Python优化最小化如何?

我希望尽量减少功能如下:

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

PS:我执行与这些参数的函数:nelsonsiegel(0.01,0.01,0.01,0.01,1,1)

回答

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) 

我希望它会做

Regards,

+0

非常感谢胡安,我会努力解答你给了。 – Sitingbull