2017-08-02 6 views
0

Ich bin ein Anfänger in Python und ich versuche, diese Funktion mit der gleichen Excel Solver Logic zu minimieren, aber ich bin nicht dazu in der Lage. Kannst du mir bitte helfen?Python-Optimierung Minimieren wie?

Die Funktion, die ich minimieren wollen, ist wie folgt:

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) 

Normalerweise eine Summe es zurück. Diese Summe sollte minimiert werden, indem auf Beta0, Beta1, Beta2, Beta3, Lambda1, Lambda2 gespielt wird. Die Bedingungen für Beta0 bis Beta3 sollten so sein, dass diese Variablen zwischen -1 und 1 oszillieren können. Lambda1 und Lambda2 haben keine Einschränkungen.

Wissen Sie, wie Sie den Code zum Ausführen dieser Aufgabe schreiben? Danke SB

PS: Ich führen Sie die Funktion mit diesen Parametern: nelsonsiegel (0.01,0.01,0.01,0.01,1,1)

Antwort

0

Nun, ich würde die Gleichung umschreiben, so dass es nur ein dauert einzelnes Argument, das später bei Bedarf in die Variablen innerhalb der Funktion geparst wird. Nachdem dort der Anruf an die Optimierungs-Engine durch

ist

scipy.optimize.minimize

Daher wird das resultierende Stück Code loke wie:

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) 

Ich hoffe, es wird tun

Grüße,

+0

Vielen Dank Juan, ich werde an der Antwort arbeiten Du gabst. – Sitingbull