Wednesday, March 29, 2017

How to install QuantLib Python for Windows 32 in offline installation

1. Download Python 2.7 Windows x86 MSI installer from

https://www.python.org/ftp/python/2.7.13/python-2.7.13.msi

2. Download required python packages and dependencies from

http://www.lfd.uci.edu/~gohlke/pythonlibs/#quantlib

QuantLib_Python‑1.9‑cp27‑cp27m‑win32.whl

Dependencies for matplotlib and others (win32)
six‑1.10.0‑py2.py3‑none‑any.whl
pyparsing‑2.2.0‑py2.py3‑none‑any.whl
packaging‑16.8‑py2.py3‑none‑any.whl
appdirs-1.4.3-py2.py3-none-any.whl
python_dateutil‑2.6.0‑py2.py3‑none‑any.whl
pytz‑2016.10‑py2.py3‑none‑any.whl
cycler‑0.10.0‑py2.py3‑none‑any.whl
setuptools‑34.3.3‑py2.py3‑none‑any.whl

numpy‑1.11.3+mkl‑cp27‑cp27m‑win32.whl
matplotlib‑1.5.3‑cp27‑cp27m‑win32.whl
xlrd-1.0.0-py2.py3-none-any.whl
pandas-0.19.2-cp27-cp27m-win32.whl
scipy‑0.19.0‑cp27‑cp27m‑win32.whl

3. Copy the above Installers and Packages to destination machine for offline installation

4. Install Python 2.7 and add Environment Variable PATH

SET PATH=C:\Python27;C:\Python27\Scripts;%PATH%

To be persistence, use sysdm.cpl to edit Advanced -> Environment Variables -> Path

or use py -2 to run python script under Windows OS without setting PATH
py -2 chap06.py

5. Install each and every the python packages above using pip

For example
pip install QuantLib_Python‑1.9‑cp27‑cp27m‑win32.whl

or if have python2 and python3 co-exist

py -2 -m pip install QuantLib_Python‑1.9‑cp27‑cp27m‑win32.whl

6. Microsoft Visual Studio not required

and no need to build your own QuantLib-Python library
However, a code editor like Microsoft VS Code is recommended.
https://code.visualstudio.com/download
(requirement : .NET Framework 4.5.2 for Windows 7)

Offline VS code extension for python can be downloaded from
https://donjayamanne.gallery.vsassets.io/_apis/public/gallery/publisher/donjayamanne/extension/python/0.6.0/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage
see stack overflow discussion here http://stackoverflow.com/questions/37071388/how-to-install-vscode-extensions-offline

or NotePad ++
https://notepad-plus-plus.org/download/


7. Test

The code is borrowed from QuantLib Python Cookbook chapter 06
chap06.py    Select all
#! python2 #!/usr/bin/env python # pylint: disable-msg=C0103 # Interest-rate Curves # Chapter 6 EONIA curve bootstrapping # Everything You Always Wanted to Know About Multiple Interest Rate Curve Bootstrapping but Were Afraid to Ask # In[1] import math # In[2] from QuantLib import * print "\nOut[1]:" print "QuantLib version", QuantLib.__version__ # In[3] # setup evaluationDate today = Date(11, December,2012) Settings.instance().evaluationDate = today # In[4] # setup DepositRateHelper for 0-2 days helpers = [ DepositRateHelper(QuoteHandle(SimpleQuote(rate/100)), Period(1,Days), fixingDays, TARGET(), Following, False, Actual360()) for rate, fixingDays in [(0.04, 0), (0.04, 1), (0.04, 2)] ] # DepositRateHelper (const Handle< Quote > &rate, # const Period &tenor, # Natural fixingDays, # const Calendar &calendar, # BusinessDayConvention convention, # bool endOfMonth, # const DayCounter &dayCounter) # DepositRateHelper (Rate rate, # const Period &tenor, # Natural fixingDays, # const Calendar &calendar, # BusinessDayConvention convention, # bool endOfMonth, # const DayCounter &dayCounter) # In[5] """ Eonia(const Handle< YieldTermStructure > &h=Handle< YieldTermStructure >()) Eonia (Euro Overnight Index Average) rate fixed by the ECB HKDHibor(const Period &tenor, const Handle< YieldTermStructure > &h=Handle< YieldTermStructure >()) """ eonia = Eonia() """ http://quant.stackexchange.com/questions/32345/quantlib-python-dual-curve-bootstrapping-example swap-rate helpers used to bootstrap the LIBOR curve can take a discount curve to use. In the old single-curve examples, a SwapRateHelper instance would be created as helper = SwapRateHelper(quoted_rate, tenor, calendar, fixedLegFrequency, fixedLegAdjustment, fixedLegDayCounter, Euribor6M()) and use the curve being bootstrapped for both forecast and discounting. To use dual-curve bootstrapping, instead, you'll have to build it as helper = SwapRateHelper(quoted_rate, tenor, calendar, fixedLegFrequency, fixedLegAdjustment, fixedLegDayCounter, Euribor6M(), QuoteHandle(), Period(0,Days), # needed as default value discountCurve) # the discountCurve argument would be a handle to the OIS curve that you bootstrapped previously SwapRateHelper (Rate rate, const Period &tenor, const Calendar &calendar, Frequency fixedFrequency, BusinessDayConvention fixedConvention, const DayCounter &fixedDayCount, const boost::shared_ptr< IborIndex > &iborIndex, const Handle< Quote < &spread=Handle< Quote >(), const Period &fwdStart=0 *Days, const Handle< YieldTermStructure > &discountingCurve=Handle< YieldTermStructure >()) In the above, the additional QuoteHandle() and Period(0,Days) arguments are, unfortunately, needed because the SWIG wrappers don't support keyword arguments for this constructor; and the discountCurve argument would be a handle to the OIS curve that you bootstrapped previously. When the swap-rate helpers are instantiated as above, they will use the LIBOR curve being bootstrapped for forecast and the OIS curve for discounting. """ # In[6] # Overnight Index Swap rate # setup OISRateHelper for 1,2,3 weeks and 1 month helpers += [ OISRateHelper(2, Period(*tenor), QuoteHandle(SimpleQuote(rate/100)), eonia) for rate, tenor in [(0.070, (1,Weeks)), (0.069, (2,Weeks)), (0.078, (3,Weeks)), (0.074, (1,Months))] ] # In[7] """ DatedOISRateHelper(const Date &startDate, const Date &endDate, const Handle< Quote > &fixedRate, const boost::shared_ptr< OvernightIndex > &overnightIndex) """ # setup DatedOISRateHelper helpers += [ DatedOISRateHelper(start_date, end_date, QuoteHandle(SimpleQuote(rate/100)), eonia) for rate, start_date, end_date in [(0.046, Date(16,January,2013), Date(13,February,2013)), (0.016, Date(13,February,2013), Date(13,March,2013)), (-0.007, Date(13,March,2013), Date(10,April,2013)), (-0.013, Date(10,April,2013), Date(8,May,2013)), (-0.014, Date(8,May,2013), Date(12,June,2013))] ] # In[8] """ Overnight Index Swap rate OISRateHelper(Natural settlementDays, const Period &tenor, const Handle< Quote > &fixedRate, const boost::shared_ptr< OvernightIndex > &overnightIndex) """ # setup OISRateHelper from 15 months to 30 years helpers += [ OISRateHelper(2, Period(*tenor), QuoteHandle(SimpleQuote(rate/100)), eonia) for rate, tenor in [(0.002, (15,Months)), (0.008, (18,Months)), (0.021, (21,Months)), (0.036, (2,Years)), (0.127, (3,Years)), (0.274, (4,Years)), (0.456, (5,Years)), (0.647, (6,Years)), (0.827, (7,Years)), (0.996, (8,Years)), (1.147, (9,Years)), (1.280, (10,Years)), (1.404, (11,Years)), (1.516, (12,Years)), (1.764, (15,Years)), (1.939, (20,Years)), (2.003, (25,Years)), (2.038, (30,Years))] ] # In[9] eonia_curve_c = PiecewiseLogCubicDiscount(0, TARGET(), helpers, Actual365Fixed()) """ # QuantLib-SWIG/SWIG/piecewiseyieldcurve.i %define export_piecewise_curve(Name, Base, Interpolator) export_piecewise_curve(PiecewiseLogCubicDiscount, Discount, MonotonicLogCubic); PiecewiseYieldCurve<Base,Interpolator>( settlementDays, # Integer settlementDays, calendar, # const Calendar& calendar, instruments, # const std::vector<boost::shared_ptr<RateHelper> >& instruments, dayCounter, # const DayCounter& dayCounter, jumps, # const std::vector<Handle<Quote> >& jumps=std::vector<Handle<Quote> >(), jumpDates, # const std::vector<Date>& jumpDates = std::vector<Date>(), accuracy, # Real accuracy = 1.0e-12, i # const Interpolator& i = Interpolator() ) """ eonia_curve_c.enableExtrapolation() # In[10] today = eonia_curve_c.referenceDate() end = today+Period(2,Years) dates = [ Date(serial) for serial in range(today.serialNumber(), end.serialNumber()+1) ] rates_c = [ eonia_curve_c.forwardRate(d, TARGET().advance(d, 1, Days), Actual360(), Simple).rate()*100 for d in dates ] # In[11] import matplotlib.pyplot as plt plt.title("Multiple Interest Rate Curve Bootstrapping") plt.plot(rates_c, '-') plt.ylabel('Rates') plt.show() # get spot rates spots = [] tenors = [] today = eonia_curve_c.referenceDate() end = today+Period(2,Years) dates = [ Date(serial) for serial in range(today.serialNumber(), end.serialNumber()+1) ] #for d in eonia_curve_c.dates(): # return boost::dynamic_pointer_cast<Name>(*self)->dates(); for d in dates: day_count = Actual360() yrs = day_count.yearFraction(today, d) compounding = Simple freq = Annual zero_rate = eonia_curve_c.zeroRate(yrs, compounding, freq) tenors.append(yrs) eq_rate = zero_rate.equivalentRate(day_count, compounding, freq, today, d).rate() spots.append(100*eq_rate) plt.title('Discount Curve') plt.plot(tenors[1::], spots[1::], linewidth=2.0) plt.xlabel('tenor (Y)') plt.ylabel('spot (%)') plt.show()





8. Test2, requires QuantLib, numpy, scipy, matplotlib

The code is borrowed from QuantLib Python Cookbook chapter 13
chap13.py    Select all
#! python2 #!/usr/bin/env python # pylint: disable-msg=C0103 # Interest-rate Models # Chapter 13 Thoughts on the Convergence of Hull-White Model Monte-Carlo Simulations # In[1] import QuantLib as ql print "\nOut[1]:" print "QuantLib version", ql.__version__ import matplotlib.pyplot as plt import numpy as np from scipy.integrate import simps, cumtrapz, romb # % matplotlib inline import math todays_date = ql.Date(15, 1, 2015) ql.Settings.instance().evaluationDate = todays_date # In[2] # <!-- collapse=True --> def get_path_generator(timestep, hw_process, length, low_discrepancy=False, brownian_bridge=True): """ Returns a path generator The `get_path_generator` function creates the a path generator. This function takes various inputs such as """ if low_discrepancy: usg = ql.UniformLowDiscrepancySequenceGenerator(timestep) rng = ql.GaussianLowDiscrepancySequenceGenerator(usg) seq = ql.GaussianSobolPathGenerator( hw_process, length, timestep, rng,brownian_bridge) else: usg = ql.UniformRandomSequenceGenerator(timestep, ql.UniformRandomGenerator()) rng = ql.GaussianRandomSequenceGenerator(usg) seq = ql.GaussianPathGenerator( hw_process, length, timestep, rng, brownian_bridge) return seq # In[3] # <!-- collapse=True --> def generate_paths(num_paths, timestep, seq): """ The `generate_paths` function uses the generic path generator produced by the `get_path_generator` function to return a tuple of the array of the points in the time grid and a matrix of the short rates generated." """ arr = np.zeros((num_paths, timestep+1)) for i in range(num_paths): sample_path = seq.next() path = sample_path.value() time = [path.time(j) for j in range(len(path))] value = [path[j] for j in range(len(path))] arr[i, :] = np.array(value) return np.array(time), arr # In[4] # <!-- collapse=True --> def generate_paths_zero_price(spot_curve_handle, a, sigma, timestep, length, num_paths, avg_grid_array, low_discrepancy=False, brownian_bridge=True): """ This function returns a tuple (T_array, F_array), where T_array is the array of points in the time grid, and F_array is the array of the average of zero prices observed from the simulation. The `generate_paths_zero_price` essentially is a wrapper around `generate_path_generator` and `generate_paths` taking all the required raw inputs. This function returns the average of zero prices from all the paths for different points in time. I wrote this out so that I can conveniently change all the required inputs and easily plot the results." """ hw_process = ql.HullWhiteProcess(spot_curve_handle, a, sigma) seq = get_path_generator( timestep, hw_process, length, low_discrepancy, brownian_bridge ) time, paths = generate_paths(num_paths, timestep, seq) avgs = [(time[j], (np.mean([math.exp(-simps(paths[i][0:j], time[0:j])) for i in range(num_paths)]))) for j in avg_grid_array ] return zip(*avgs) def generate_paths_discount_factors(spot_curve_handle, a, sigma, timestep, length, num_paths, avg_grid_array, low_discrepancy=False, brownian_bridge=True): """ This function returns a tuple (T_array, S_matrix), where T_array is the array of points in the time grid, and S_matrix is the matrix of the spot rates for each path in the different points in the time grid. """ hw_process = ql.HullWhiteProcess(spot_curve_handle, a, sigma) seq = get_path_generator( timestep, hw_process, length, low_discrepancy, brownian_bridge ) time, paths = generate_paths(num_paths, timestep, seq) arr = np.zeros((num_paths, len(avg_grid_array))) for i in range(num_paths): arr[i, :] = [np.exp(-simps(paths[i][0:j], time[0:j])) for j in avg_grid_array ] t_array = [time[j] for j in avg_grid_array] return t_array, arr def V(t,T, a, sigma): """ Variance of the integral of short rates, used below """ return sigma*sigma/a/a*(T-t + 2.0/a*math.exp(-a*(T-t)) - 1.0/(2.0*a)*math.exp(-2.0*a*(T-t)) - 3.0/(2.0*a) ) # In[5] # <!-- collapse=True --> # Here we vary sigma with fixed a and observe the error epsilon # define constants num_paths = 500 sigma_array = np.arange(0.01,0.1,0.03) a = 0.1 timestep = 180 length = 15 # in years forward_rate = 0.05 day_count = ql.Thirty360() avg_grid_array = np.arange(12, timestep+1, 12) # generate spot curve spot_curve = ql.FlatForward( todays_date, ql.QuoteHandle(ql.SimpleQuote(forward_rate)), day_count ) spot_curve_handle = ql.YieldTermStructureHandle(spot_curve) #initialize plots figure, axis = plt.subplots() plots = [] zero_price_theory = np.array([spot_curve.discount(j*float(length)/float(timestep)) for j in avg_grid_array]) for sigma in sigma_array: term, zero_price_empirical = generate_paths_zero_price( spot_curve_handle, a, sigma, timestep, length, num_paths, avg_grid_array ) plots += axis.plot( term, np.abs(zero_price_theory - np.array(zero_price_empirical)), lw=2, alpha=0.6, label="$\sigma=$"+str(sigma) ) # plot legend labels = [p.get_label() for p in plots] legend =axis.legend(plots,labels, loc=0)#, loc=0, bbox_to_anchor=(1.1,0.4)) axis.set_xlabel("T (years)", size=12) axis.set_ylabel("|$\epsilon(T)$|", size=12) axis.set_title("Out[5]:Discount Factor Error for $a=$%0.2f and Varying $\sigma$"%a, size=14) plt.show() # In[6] # <!-- collapse=True --> # Here we vary a with fixed sigma and observe the error epsilon # define constants num_paths = 500 sigma = 0.1 a_array = np.arange(0.1, 0.51, 0.1) timestep = 180 length = 15 # in years forward_rate = 0.05 day_count = ql.Thirty360() avg_grid_array = np.arange(12, timestep+1, 12) # generate spot curve spot_curve = ql.FlatForward( todays_date, ql.QuoteHandle(ql.SimpleQuote(forward_rate)), day_count ) spot_curve_handle = ql.YieldTermStructureHandle(spot_curve) #initialize plots figure, axis = plt.subplots() plots = [] zero_price_theory = np.array([spot_curve.discount(j*float(length)/float(timestep)) for j in avg_grid_array]) for a in a_array: term, zero_price_empirical = generate_paths_zero_price( spot_curve_handle, a, sigma, timestep, length, num_paths, avg_grid_array ) plots += axis.plot( term,np.abs(zero_price_theory - np.array(zero_price_empirical)), lw=2, alpha=0.6, label="a="+str(a) ) # plot legend labels = [p.get_label() for p in plots] legend =axis.legend(plots,labels, loc=0)#, loc=0, bbox_to_anchor=(1.1,0.4)) axis.set_xlabel("T (years)", size=12) axis.set_ylabel("|$\\epsilon(T)$|", size=12) axis.set_title("Out[6]:Discount Factor Error for $\sigma$=%0.2f and Varying $a$"%sigma, size=14) plt.show() # In[7] # <!-- collapse=True --> #define constants num_paths = 500 sigma = 0.02 a = 0.1 timestep = 180 length = 15 # in years forward_rate = 0.05 day_count = ql.Thirty360() avg_grid_array = np.arange(1, timestep+1, 12) # generate spot curve spot_curve = ql.FlatForward( todays_date, ql.QuoteHandle(ql.SimpleQuote(forward_rate)), day_count ) spot_curve_handle = ql.YieldTermStructureHandle(spot_curve) term, discount_factor_matrix = generate_paths_discount_factors( spot_curve_handle, a, sigma, timestep, length, num_paths, avg_grid_array ) vol = [np.var(discount_factor_matrix[:, i]) for i in range(len(term))] l1 = plt.plot(term, 100*np.sqrt(vol),"b", lw=2, alpha=0.6, label="Empirical") vol_theory = [100*np.sqrt(math.exp(V(0,T,a, sigma))-1.0) * spot_curve_handle.discount(T) for T in term] l2 = plt.plot(term, vol_theory,"r--", lw=2, alpha=0.6, label="Theory") plots = l1+l2 labels = [p.get_label() for p in plots] legend =plt.legend(plots,labels, loc=0) plt.xlabel("Time (Years)", size=12) plt.ylabel("$\sigma_D(0,T)$ (%)", size=12) plt.title("Out[7]:Standard Deviation of Discount Factors " "(a=%0.2f, $\sigma$=%0.2f)"%(a, sigma), size=14) plt.show()




9. Test3, requires QuantLib, numpy, panda, xlrd

The code is using QuantLib, numpy, panda and xlrd to read xls data
testreadxls.py    Select all
#! python2 #!/usr/bin/env python # pylint: disable-msg=C0103 # pylint: disable-msg=C0301 # testreadxls.p import os import pandas import numpy as np import QuantLib as ql xls_file = os.path.dirname(os.path.realpath(__file__)) + '/usd_market_data_2016-07-13.xls' xl = pandas.ExcelFile(xls_file) print xl.sheet_names df = xl.parse("usdstd") #df = xl.parse(0) # alternate way to read first worksheet filename = xls_file sheetname = 'usdois' sheet = pandas.read_excel(filename, sheetname) # Read an Excel table into a pandas DataFrame #sheet = pandas.read_excel(filename, 0) # alternate way to read first worksheet instead of name print sheet.columns #tenors = np.array([Date.from_timestamp(d).t for d in sheet['dates']]) today = ql.Date(21,3,2016) act365 = ql.Actual365Fixed() dates = np.array([ql.Date(d.day, d.month, d.year) for d in sheet['dates']]) #dates = np.array([ql.Date(d.day, d.month, d.year) for d in df.iloc[0:,0]]) # use iloc to read first column, all rows print "\nusd_market_data_2016-07-13.xls dates column" print dates tenors = np.array([act365.yearFraction(today,ql.Date(d.day, d.month, d.year)) for d in sheet['dates']]) print "\nusd_market_data_2016-07-13.xls dates column convert to tenor" print tenors print "\nusd_market_data_2016-07-13.xls discounts column" discounts = np.array(sheet['discounts'].tolist()) #discounts = np.array(df.iloc[0:,1].tolist()) # use iloc to read second column, all rows print discounts


Assume the usd_market_data_2016-07-13.xls sheet usdois (first worksheet) has the following data


10. Test3, requires QuantLib, pandas, matplotlib

The code demonstrates the download of Interest Rate xml market data from markit.com and Bootstrapping IR Curve in QuantLib
test_xml_download.py    Select all
#!python2 #!/usr/bin/env python # pylint: disable-msg=C0103 # pylint: disable-msg=C0301 # test_xml_download.py from QuantLib import * print "\nQuantLib version", QuantLib.__version__ import urllib import zipfile import xml.etree.ElementTree as ET import pandas as pd import datetime as dt from matplotlib.dates import YearLocator, MonthLocator, DateFormatter from matplotlib.ticker import FuncFormatter def to_datetime(d): """ to_datetime """ return dt.datetime(d.year(), d.month(), d.dayOfMonth()) def format_rate(r, p=2): """ format_rate """ return '{0:.{prec}f}%'.format(r*100.00, prec=p) period_dict = {str(k)+'M': (k, Months) for k in range(1, 12, 1)} d2 = {str(k)+'Y': (k, Years) for k in range(1, 50, 1)} period_dict.update(d2) (ir_currency, ir_date) = ('USD', '20170331') url = 'https://www.markit.com/news/InterestRates_%s_%s.zip' % (ir_currency, ir_date) filehandle, _ = urllib.urlretrieve(url) zip_file_object = zipfile.ZipFile(filehandle, 'r') interest_rate_file = zip_file_object.open(zip_file_object.namelist()[1]) content = interest_rate_file.read() #print content root = ET.fromstring(content) print "\nInfo on InterestRates_%s_%s" % (ir_currency, ir_date) for a in [root.find(b) for b in ['./currency', './effectiveasof', './deposits/daycountconvention', './deposits/snaptime', './deposits/spotdate', './swaps/fixeddaycountconvention', './swaps/floatingdaycountconvention', './swaps/snaptime', './swaps/spotdate']]: print a.tag, a.text effectiveasof = root.find('./effectiveasof').text currency = root.find('./currency').text today = DateParser.parseFormatted(effectiveasof, '%Y-%m-%d') Settings.instance().evaluationDate = today print "\nDeposit Rates" deposits_maturitydates = [a.text for a in root.findall('.//deposits/curvepoint/maturitydate')] deposits_parrates_text = [a.text for a in root.findall('.//deposits/curvepoint/parrate')] deposits_tenors = [a.text for a in root.findall('.//deposits/curvepoint/tenor')] deposits_periods = [period_dict[a] for a in deposits_tenors] print pd.DataFrame(zip(deposits_tenors, deposits_maturitydates, map(float, deposits_parrates_text)), columns=('Tenor', 'Maturity', 'Parrate')) maturity_dict = {} for t, m in zip(deposits_tenors, deposits_maturitydates): d = {t: m} maturity_dict.update(d) print "\nSwap Rates" swaps_maturitydates = [a.text for a in root.findall('.//swaps/curvepoint/maturitydate')] swaps_parrates_text = [a.text for a in root.findall('.//swaps/curvepoint/parrate')] swaps_tenors = [a.text for a in root.findall('.//swaps/curvepoint/tenor')] swaps_periods = [period_dict[a] for a in swaps_tenors] print pd.DataFrame(zip(swaps_tenors, swaps_maturitydates, map(float, swaps_parrates_text)), columns=('Tenor', 'Maturity', 'Parrate')) for t, m in zip(swaps_tenors, swaps_maturitydates): d = {t: m} maturity_dict.update(d) #print maturity_dict euribor6m = Euribor6M() helpers = [DepositRateHelper(rate, Period(*tenor), 2, TARGET(), Following, False, Actual360()) for tenor, rate in zip(deposits_periods, map(float, deposits_parrates_text))] helpers += [SwapRateHelper(rate, Period(*tenor), TARGET(), Semiannual, Unadjusted, Thirty360(), euribor6m) for tenor, rate in zip(swaps_periods, map(float, swaps_parrates_text))] curve = PiecewiseLogCubicDiscount(2, TARGET(), helpers, Actual360()) curve.enableExtrapolation() spot = curve.referenceDate() #dates = [spot+Period(i,Months) for i in range(0, 30*12+1)] dates = [spot+Period(i, Years) for i in range(0, 30)] rates = [curve.forwardRate(d, euribor6m.maturityDate(d), Actual360(), Simple).rate() for d in dates] valid_dates = [d for d in dates if d >= spot] import matplotlib.pyplot as plt fig, ax = plt.subplots() fig.autofmt_xdate() ax.plot_date([to_datetime(d) for d in valid_dates], rates, '-') ax.set_xlim(to_datetime(min(dates)), to_datetime(max(dates))) ax.xaxis.set_major_locator(YearLocator(2, month=today.month(), day=today.dayOfMonth())) ax.xaxis.set_major_formatter(DateFormatter("%Y")) ax.xaxis.grid(True, 'major') ax.xaxis.grid(False, 'minor') ax.yaxis.set_major_formatter(FuncFormatter(lambda r, pos: format_rate(r))) plt.title("%s Interest Rate Curve Bootstrapping, effective %s" % (currency, effectiveasof)) plt.xlabel('Year') plt.ylabel('Rates') plt.show()






11. Compile QuantLib Python 1.10 for Mac

script.sh    Select all
# install Xcode and HomeBrew # ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" # install boost brew install boost # Download QuantLib-1.10 cd $(HOME)/Downloads wget --no-check-certificate https://jaist.dl.sourceforge.net/project/quantlib/test/QuantLib-1.10.tar.gz tar xzvf QuantLib-1.10.tar.gz # Compile QuantLib 1.10 cd QuantLib-1.10 ./configure --prefix=/usr/local/ CXXFLAGS='-O2 -stdlib=libstdc++ -mmacosx-version-min=10.6' LDFLAGS='-stdlib=libstdc++ -mmacosx-version-min=10.6' make && sudo make install # test compile c++ g++ Bonds.cpp -std=c++11 -stdlib=libstdc++ -o Bonds -lQuantLib ./Bonds # Download QuantLib-SWIG 1.10 cd $(HOME)/Downloads wget --no-check-certificate https://jaist.dl.sourceforge.net/project/quantlib/test/QuantLib-SWIG-1.10.tar.gz tar xzvf QuantLib-SWIG-1.10.tar.gz # Compile QuantLib Python cd QuantLib-SWIG-1.10 ./configure CXXFLAGS='-O2 -stdlib=libstdc++ -mmacosx-version-min=10.6' make -C Python make -C Python check sudo make -C Python install # Package wheel file sudo -H python pip install setuptools wheel cd $(HOME)/Downloads/QuantLib-SWIG-1.10/Python # Modify setup.py and replace from distutils.core import setup, Extension # With from setuptools import setup from distutils.core import Extension # python 2 wheel file python setup.py bdist_wheel ls dist/ # python 3 wheel file LDFLAGS="-arch x86_64 -bundle -flat_namespace -undefined suppress" CFLAGS="-fno-strict-aliasing -Wsign-compare -fno-common -static -arch x86_64 -Wno-shorten-64-to-32" python3 setup.py bdist_wheel ls dist/


QuantLib_Python-1.10-cp27-cp27m-macosx_10_10_intel.whl download

QuantLib_Python-1.10-cp36-cp36m-macosx_10_6_intel.whl download
For Python3, have to install libQuantLib to /usr/local/lib
cd /usr/local/lib
sudo tar xzvf ~/Download/libQuantLib.tgz
Download libQuantLib.tgz here https://mega.nz/#!rpJg0B6T!NlG3Ijgo0weNOi_CVOkCzpGCMRqHZkWSeF3S0sAR12o



12. For Windows 64-bit, Regeneration of python SWIG interface method
If you need to edit the SWIG interface file and add functionality in QuantLib Python, you need to regenerate.


script.cmd    Select all
# First, compile QuantLib using Visual Studio 2015. # Select All Configurations and All Platforms. Add C:\local\boost_1_59_0; to the Property Pages : VC++ Include directories. # Add /wd4819 to Command Line : Additional Options to disable C4819 warnings when compiling Quantlib. # Build Release x64 Solution. # setting of QuantLib Project directory, e.g. SET QL_DIR=C:\local\QuantLib-1.10\QuantLib-1.10 # or alternatively, edit the setup.py # QL_INSTALL_DIR = 'C:\local\QuantLib-1.10\QuantLib-1.10' # setting of compiled libraries location for QuantLib ('QuantLib-vc140-x64-mt.lib') and Boost, e.g. SET LIB=C:\local\boost_1_59_0_64\lib64-msvc-14.0;C:\local\QuantLib-1.10\QuantLib-1.10\lib # or alternatively, edit the setup.py # self.library_dirs += [os.path.join(QL_INSTALL_DIR, 'lib')] + ['C:\local\boost_1_59_0_64\lib64-msvc-14.0'] # setting of Boost Project directory, e.g. SET INCLUDE=C:\local\boost_1_59_0_64 # or alternatively, edit the setup.py # self.include_dirs += [QL_INSTALL_DIR] + ['C:\local\boost_1_59_0_64'] # setting of SWIGWIN.exe PATH, e.g. SET PATH=C:\local\swigwin-3.0.12;%PATH% # setting of VISUAL STUDIO 2015 (Version 14) SET VS90COMNTOOLS=%VS140COMNTOOLS% # Edit SWIG interface file if any C:\local\QuantLib-1.10\QuantLib-SWIG-1.10\SWIG\*.i # e.g. edit piecewiseyieldcurve.i and add at the end # export_piecewise_curve(PiecewiseLogLinearDiscount,Discount,LogLinear); # Wrap the edited interface file again after edit py -2 setup.py wrap # compile using msvc # need to edit setup.py to add '/wd4819' to the extra_compile_args to disable warnings py -2 setup.py build --compiler=msvc # must use Administrator Command Prompt to install py -2 -m setup.py install --skip-build # generation of wheel file is same as above that is modify setup.py first # need to install setuptools and wheel py -2 -m pip install setuptools wheel py -2 setup.py test py -2 setup.py bdist_wheel


Visual Studio 2015 setup https://mega.nz/#!70ZwyARa!z4et3sKwguU16tEbCYTdwBC1VEkNJTTakryrDRBSKM8


No comments: