diff --git a/NS SS bond curve.py b/NS SS bond curve.py new file mode 100644 index 0000000..034c277 --- /dev/null +++ b/NS SS bond curve.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Nov 12 10:12:45 2018 + +@author: Shinhyunjin +""" + +""" +Topic: Nelson-Siegel Curve Smoothing Technique +Sources: Generating a Yield Curve with Nelson-Seigel Method in Excel -> https://www.youtube.com/watch?v=GsZRJmDcDbY + Data fitting using fmin -> http://glowingpython.blogspot.it/2011/05/curve-fitting-using-fmin.html + +Comment: Refer to the above video for an explanation of the method. Also see https://github.com/MaximumBeings/public/blob/master/NSSandNS.txt + for an MS Excel version of the NSS and NS method. Though the code works very + well, we noticed that the Excel version fitted our original data better because the solver in Excel is pretty powerful. Nonetheless, + this is a very good implementation of the NSS method. We try to fit the curve by minimizing the sum of squared errors using the + NS formula. It is an iterative method that tries to guess the values for the NS parameters so you need to try different initial + values. Feed the program with a set of initial values and observe the curve plot and change the parameters to get better fits. A good + starting set of initial values is array([0.01,0.01,0.01,1.00]) but can be changed to get a better fit. +""" + + + +import pylab +from numpy import * +from scipy.optimize import fmin +import pandas as pd +import os +import numpy as np +import matplotlib.pyplot as plt + + +### Nelson - Siegel ### + +pre1 = os.path.dirname(os.path.realpath('C:/Users/Shinhyunjin/Dropbox/hw1data.xlsx')) +fname1 = 'hw1data.xlsx' +path1 = os.path.join(pre1, fname1) +df1 = pd.read_excel(path1) +data = pd.DataFrame(df1) + + +#print "" +# parametric function, x is the independent variable +# and c are the parameters. +# it's a polynomial of degree 2 +fp = lambda c, x: c[0]+(c[1]+c[2])*(c[3]/x)*(1-exp(-x/c[3])-c[2]*exp(-x/c[3])) + +# error function to minimize +e = lambda p, x, y: ((fp(p,x)-y)**2).sum() + + +# generating data with noise + +y = np.array(data['YTM']/100) #The periods for which data are available, skip the periods with empty rate +x = np.array(data['TAU']) #Available rates only + +# fitting the data with fmin +p0 = array([0.01,0.01,0.01,1.00]) # initial parameter value +p = fmin(e, p0, args=(x,y)) +c = p +j=[] + +for h in x: + j.append(c[0]+(c[1]+c[2])*(c[3]/h)*(1-exp(-h/c[3])-c[2]*exp(-h/c[3]))) + + +#print "" +print ('Initial Parameters: ', p0) +print ('Estimated Parameters: ', p) + + + +#To display interpolated data. +h = x +rateTable = pd.DataFrame.from_items([('Period', h),('NS', j)]) +print(rateTable.to_string()) + +#xx = +pylab.plot(x,y, 'b') +pylab.plot(x, fp(p,x), 'ro') +pylab.title('Nelson-Siegel') +pylab.show() + + + +#### Svensson #### + +# parametric function, x is the independent variable +# and c are the parameters. +# it's a polynomial of degree 2 +fp2 = lambda c2, x: (c2[0])+ (c2[1]*((1- exp(-x/c2[4]))/(x/c2[4])))+ (c2[2]*((((1-exp(-x/c2[4]))/(x/c2[4])))- (exp(-x/c2[4]))))+ (c2[3]*((((1-exp(-x/c2[5]))/(x/c2[5])))- (exp(-x/c2[5])))) +real_p = array([0.02,0.01,0.01,0.01,1.00,1.00]) + +# error function to minimize +e2 = lambda p2, x, y: ((fp2(p2,x)-y)**2).sum() + +# generating data with noise + +# fitting the data with fmin +p02 = array([0.01,0.01,0.01,0.01,0.01,1.00,1.00]) # initial parameter value +p2 = fmin(e2, p02, args=(x,y)) +c2 = p2 +j2=[] +for h2 in x: + j2.append((c2[0])+ (c2[1]*((1- exp(-h2/c2[4]))/(h2/c2[4])))+ (c2[2]*((((1-exp(-h2/c2[4]))/(h2/c2[4])))- (exp(-h2/c2[4]))))+ (c2[3]*((((1-exp(-h2/c2[5]))/(h2/c2[5])))- (exp(-h2/c2[5]))))) + +print ('Initial Parameters: ', p02) + +print ('Estimated Parameters: ', p2) + + +#To display interpolated data. + +h2 = x +rateTable = pd.DataFrame.from_items([('Period', h2),('NSS', j2)]) +print(rateTable.to_string()) + + +#xx = array([1,2,5,10,25,30]) +plt.title('Result') +plt.grid(True) +plt.plot(x, y, 'g') +plt.plot(x, fp2(p2,x), '--', label = 'SS') +plt.plot(x, fp2(p2,x), 'bo') +plt.plot(x, fp(p,x), 'ro') +plt.plot(x, fp(p,x), ':', label = 'NS') +plt.legend(loc=0) +plt.xlabel('Mat') +plt.ylabel('YTM') + +plt.show() + diff --git a/sswtioil.csv b/sswtioil.csv new file mode 100644 index 0000000..2bf9e04 --- /dev/null +++ b/sswtioil.csv @@ -0,0 +1,244 @@ +date,close,volume +2018-11-09,21860,38677 +2018-11-08,22235,13358 +2018-11-07,22240,7751 +2018-11-06,22625,26615 +2018-11-05,22615,10842 +2018-11-02,22950,12808 +2018-11-01,23370,6178 +2018-10-31,23895,10443 +2018-10-30,24180,7659 +2018-10-29,24235,5681 +2018-10-26,23985,8381 +2018-10-25,23915,3319 +2018-10-24,23985,30060 +2018-10-23,24875,2859 +2018-10-22,25055,3311 +2018-10-19,24840,6769 +2018-10-18,25115,7725 +2018-10-17,25920,3739 +2018-10-16,25725,9848 +2018-10-15,25820,2893 +2018-10-12,25790,6459 +2018-10-11,25915,8100 +2018-10-10,26880,4190 +2018-10-08,26560,19906 +2018-10-05,26910,5151 +2018-10-04,27395,25589 +2018-10-02,27260,28117 +2018-10-01,26430,13509 +2018-09-28,25975,2115 +2018-09-27,26030,38746 +2018-09-21,25320,1977 +2018-09-20,25605,19900 +2018-09-19,25055,5205 +2018-09-18,24625,2965 +2018-09-17,24740,2189 +2018-09-14,24650,3961 +2018-09-13,25065,14313 +2018-09-12,25040,9086 +2018-09-11,24265,1571 +2018-09-10,24495,1035 +2018-09-07,24390,1391 +2018-09-06,24600,3038 +2018-09-05,24785,3732 +2018-09-04,25215,2212 +2018-09-03,25005,2401 +2018-08-31,25180,13915 +2018-08-30,25005,42834 +2018-08-29,24575,61957 +2018-08-28,24630,4604 +2018-08-27,24585,17955 +2018-08-24,24530,12493 +2018-08-23,24350,14580 +2018-08-22,23720,4000 +2018-08-21,23555,9907 +2018-08-20,23375,543 +2018-08-17,23275,5454 +2018-08-16,23165,35758 +2018-08-14,24000,9871 +2018-08-13,24035,27421 +2018-08-10,23625,16041 +2018-08-09,23815,24546 +2018-08-08,24565,2391 +2018-08-07,24590,1668 +2018-08-06,24390,26440 +2018-08-03,24490,2027 +2018-08-02,24095,4039 +2018-08-01,24280,5034 +2018-07-31,24760,26428 +2018-07-30,24520,1124 +2018-07-27,24665,1766 +2018-07-26,24645,2762 +2018-07-25,24430,6838 +2018-07-24,24070,23609 +2018-07-23,24190,2353 +2018-07-20,24270,15085 +2018-07-19,24020,4506 +2018-07-18,23735,23613 +2018-07-17,23785,5200 +2018-07-16,24615,4096 +2018-07-13,24650,6027 +2018-07-12,24735,10228 +2018-07-11,25600,9351 +2018-07-10,25795,2815 +2018-07-09,25760,2351 +2018-07-06,25475,5964 +2018-07-05,25680,8114 +2018-07-04,25960,19263 +2018-07-03,26035,5424 +2018-07-02,25525,27808 +2018-06-29,25505,19344 +2018-06-28,25235,6776 +2018-06-27,24595,14079 +2018-06-26,23765,7281 +2018-06-25,23775,9001 +2018-06-22,23050,1696 +2018-06-21,22755,1670 +2018-06-20,22830,2120 +2018-06-19,22660,2353 +2018-06-18,22305,6302 +2018-06-15,23220,1451 +2018-06-14,23090,682 +2018-06-12,23010,621 +2018-06-11,22795,1134 +2018-06-08,22840,7277 +2018-06-07,22595,3759 +2018-06-05,22565,3629 +2018-06-04,22820,1678 +2018-06-01,23250,2010 +2018-05-31,23645,3313 +2018-05-30,23130,1806 +2018-05-29,23120,3887 +2018-05-28,23100,8572 +2018-05-25,24470,3888 +2018-05-24,24855,2566 +2018-05-23,25005,6238 +2018-05-21,24950,11257 +2018-05-18,24895,11549 +2018-05-17,24870,5268 +2018-05-16,24690,5601 +2018-05-15,24565,6343 +2018-05-14,24435,6537 +2018-05-11,24720,8108 +2018-05-10,24885,8937 +2018-05-09,24345,7149 +2018-05-08,24285,6686 +2018-05-04,23720,962 +2018-05-03,23485,2803 +2018-05-02,23435,2796 +2018-04-30,23535,1647 +2018-04-27,23565,1430 +2018-04-26,23670,2115 +2018-04-25,23480,5683 +2018-04-24,24000,2118 +2018-04-23,23660,1547 +2018-04-20,23660,4875 +2018-04-19,23830,2664 +2018-04-18,23275,1393 +2018-04-17,23080,2418 +2018-04-16,23145,3024 +2018-04-13,23160,6079 +2018-04-12,23180,11824 +2018-04-11,22570,33607 +2018-04-10,22215,3054 +2018-04-09,21600,15288 +2018-04-06,21850,355 +2018-04-05,22035,522 +2018-04-04,21880,27127 +2018-04-03,21850,3569 +2018-04-02,22575,703 +2018-03-30,22390,497 +2018-03-29,22375,2782 +2018-03-28,22360,1300 +2018-03-27,22720,7760 +2018-03-26,22675,845 +2018-03-23,22520,1114 +2018-03-22,22525,16781 +2018-03-21,21960,5399 +2018-03-20,21635,1099 +2018-03-19,21445,11645 +2018-03-16,21180,1390 +2018-03-15,21095,3923 +2018-03-14,21010,3437 +2018-03-13,21220,937 +2018-03-12,21375,4300 +2018-03-09,20835,2573 +2018-03-08,21155,1377 +2018-03-07,21445,823 +2018-03-06,21620,1857 +2018-03-05,21250,944 +2018-03-02,21065,13615 +2018-02-28,21660,1602 +2018-02-27,22015,1321 +2018-02-26,22000,1772 +2018-02-23,21630,3356 +2018-02-22,21065,1132 +2018-02-21,21100,2858 +2018-02-20,21440,1009 +2018-02-19,21470,17845 +2018-02-14,20425,1613 +2018-02-13,20555,2965 +2018-02-12,20610,1933 +2018-02-09,20880,14094 +2018-02-08,21265,6084 +2018-02-07,21935,5776 +2018-02-06,21850,10332 +2018-02-05,22380,2315 +2018-02-02,22745,4872 +2018-02-01,22320,2122 +2018-01-31,22005,4318 +2018-01-30,22315,9906 +2018-01-29,22825,6765 +2018-01-26,22510,2785 +2018-01-25,22835,6897 +2018-01-24,22190,2394 +2018-01-23,22030,3597 +2018-01-22,21800,2579 +2018-01-19,21720,4515 +2018-01-18,22030,3831 +2018-01-17,21930,9339 +2018-01-16,22175,8404 +2018-01-15,22185,4435 +2018-01-12,21820,3494 +2018-01-11,21845,4932 +2018-01-10,21850,9899 +2018-01-09,21385,2203 +2018-01-08,21180,3327 +2018-01-05,21320,1647 +2018-01-04,21380,16966 +2018-01-03,20770,7894 +2018-01-02,20895,3411 +2017-12-28,20535,3463 +2017-12-27,20515,9791 +2017-12-26,20155,4842 +2017-12-22,20030,4635 +2017-12-21,19995,7034 +2017-12-20,19885,1499 +2017-12-19,19765,673 +2017-12-18,19830,5575 +2017-12-15,19720,3386 +2017-12-14,19555,6769 +2017-12-13,19855,1442 +2017-12-12,20135,2307 +2017-12-11,19700,5892 +2017-12-08,19520,2279 +2017-12-07,19325,15604 +2017-12-06,19775,1261 +2017-12-05,19790,3119 +2017-12-04,19960,559 +2017-12-01,19865,5407 +2017-11-30,19805,21065 +2017-11-29,19840,41557 +2017-11-28,19880,1899 +2017-11-27,20190,23006 +2017-11-24,20160,3308 +2017-11-23,19955,6844 +2017-11-22,19905,8028 +2017-11-21,19475,1062 +2017-11-20,19580,2896 +2017-11-17,19145,807 +2017-11-16,19145,428 +2017-11-15,19060,6791 +2017-11-14,19565,3999 +2017-11-13,19625,6933 diff --git a/sswtioil.xlsx b/sswtioil.xlsx new file mode 100644 index 0000000..4972e82 Binary files /dev/null and b/sswtioil.xlsx differ