Hello,
I've been working for a quite long time (when some spare time is available) to learn how to use the Quantlib library with Bonds using Python. After some other previous posts (Python bond example and Python CMS test) I've been working to port the assetswap test to Python in order to get a better understanding on Quantlib/Bonds, SWIG and Python together. Please find attached the Assetswap test port to Python. It works quite well with the exception of the following issue that I cannot figure out how to solve. The real problem is on the floating bond coupon pricer that I get an error when instantiated from the generic Bond (it works well for the specialized constructor). See the following code and the exception: ## FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13) ## maturity doesn't occur on a business day floatingBondStartDate1 = Date(29,September,2003) floatingBondMaturityDate1 = Date(29,September,2013) floatingBondSchedule1 = Schedule(floatingBondStartDate1, floatingBondMaturityDate1, Period(Semiannual), bondCalendar, Unadjusted, Unadjusted, DateGeneration.Backward, False) floatingBondLeg1 = list(IborLeg([self.faceAmount],floatingBondSchedule1, self.iborIndex, Actual360(),Following,[fixingDays],[],[0.0056],[inArrears])) floatingbondRedemption1 = bondCalendar.adjust(floatingBondMaturityDate1, Following) floatingBondLeg1.append(SimpleCashFlow(100.0, floatingbondRedemption1)) ## generic bond floatingBond1 = Bond(settlementDays, bondCalendar, self.faceAmount, floatingBondMaturityDate1, floatingBondStartDate1, floatingBondLeg1) floatingBond1.setPricingEngine(bondEngine) ## equivalent specialized floater floatingSpecializedBond1 = FloatingRateBond(settlementDays, self.faceAmount, floatingBondSchedule1, self.iborIndex, Actual360(), Following, fixingDays, [1], [0.0056], [], [], inArrears, 100.0, Date(29,September,2003)) floatingSpecializedBond1.setPricingEngine(bondEngine) setCouponPricer(floatingBond1.cashflows(), self.pricer) setCouponPricer(floatingSpecializedBond1.cashflows(), self.pricer) self.iborIndex.addFixing(Date(27,March,2007), 0.0402) floatingBondTheoValue1 = floatingBond1.cleanPrice() ## The error is raised here!! floatingSpecializedBondTheoValue1 = floatingSpecializedBond1.cleanPrice() ## This works well. The exception is the following: ====================================================================== ERROR: Testing clean and dirty prices for specialized bond against equivalent generic bond... ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Quantlib-SWIG\Python\test\assetswap.py", line 2541, in testSpecializedBondVsGenericBond floatingBondTheoValue1 = floatingBond1.cleanPrice() File "C:\Python26\lib\site-packages\QuantLib\QuantLib.py", line 6505, in cleanPrice def cleanPrice(self, *args): return _QuantLib.Bond_cleanPrice(self, *args) RuntimeError: missing optionlet volatility The same error arise in some of the tests. (The code is Commented) In order to get it working I had to add the following interface (just let me know if I miss something and I will repost). In bonds.i I added the Bond Generic constructor: public: %extend { BondPtr(Natural settlementDays, const Calendar& calendar, Real faceAmount, const Date& maturityDate, const Date& issueDate = Date(), const Leg& cashflows = Leg()) { return new BondPtr( new Bond(settlementDays, calendar, faceAmount, maturityDate, issueDate, cashflows)); }; It is also needed the CMS Rate Bond constructor that is missin in the current Trunk. %{ using QuantLib::CmsRateBond; typedef boost::shared_ptr<Instrument> CmsRateBondPtr; }% %rename(CmsRateBond) CmsRateBondPtr; class CmsRateBondPtr : public BondPtr { %feature("kwargs") CmsRateBondPtr; public: %extend { CmsRateBondPtr(Size settlementDays, Real faceAmount, const Schedule& schedule, const SwapIndexPtr& index, const DayCounter& paymentDayCounter, BusinessDayConvention paymentConvention, Natural fixingDays , const std::vector<Real>& gearings , const std::vector<Spread>& spreads , const std::vector<Rate>& caps , const std::vector<Rate>& floors, bool inArrears = false, Real redemption = 100.0, const Date& issueDate = Date()){ boost::shared_ptr<SwapIndex> swap = boost::dynamic_pointer_cast<SwapIndex>(index); return new CmsRateBondPtr( new CmsRateBond(settlementDays, faceAmount, schedule, swap, paymentDayCounter, paymentConvention, fixingDays, gearings, spreads, caps, floors, inArrears, redemption, issueDate)); } } }; In the cashflows.i you need to include the interfaces included in a previous posts around CMS Bonds. In the swap.i I add the assetswap constructor: %{ using QuantLib::AssetSwap; typedef boost::shared_ptr<Instrument> AssetSwapPtr; }% %rename(AssetSwap) AssetSwapPtr; class AssetSwapPtr : public SwapPtr { public: %extend { AssetSwapPtr(bool payFixedRate, const boost::shared_ptr<Instrument>& bond, Real bondCleanPrice, InterestRateIndexPtr& index, Spread spread, const Schedule& floatSchedule = Schedule(), const DayCounter& floatingDayCount = DayCounter(), bool parAssetSwap = true){ const boost::shared_ptr<Bond> bo = boost::dynamic_pointer_cast<Bond>(bond); const boost::shared_ptr<IborIndex> iri = boost::dynamic_pointer_cast<IborIndex>(index); return new AssetSwapPtr( new AssetSwap(payFixedRate,bo,bondCleanPrice, iri,spread, floatSchedule, floatingDayCount,parAssetSwap)); } Real fairCleanPrice() { return boost::dynamic_pointer_cast<AssetSwap>(*self) ->fairCleanPrice(); } Spread fairSpread() { return boost::dynamic_pointer_cast<AssetSwap>(*self) ->fairSpread(); } } }; In addition I ammended the DiscountingEngine to include the settlementflows. (it may breach some existing code so it may make sense to overload it). %extend { DiscountingSwapEnginePtr( const Handle<YieldTermStructure>& discountCurve, bool includeSettlementDateFlows, const Date& settlementDate = Date(), const Date& npvDate = Date()) { return new DiscountingSwapEnginePtr( new DiscountingSwapEngine(discountCurve, includeSettlementDateFlows, settlementDate, npvDate)); } } In volatilities.i I added the following: // constant swaption term structure %{ using QuantLib::ConstantSwaptionVolatility; typedef boost::shared_ptr<SwaptionVolatilityStructure> ConstantSwaptionVolatilityPtr; %} %rename(ConstantSwaptionVolatility) ConstantSwaptionVolatilityPtr; class ConstantSwaptionVolatilityPtr : public boost::shared_ptr<SwaptionVolatilityStructure> { public: %extend { ConstantSwaptionVolatilityPtr(Natural settlementDays, const Calendar& cal, BusinessDayConvention bdc, const Handle<Quote>& volatility, const DayCounter& dc){ return new ConstantSwaptionVolatilityPtr( new ConstantSwaptionVolatility(settlementDays, cal, bdc, volatility,dc)); } ConstantSwaptionVolatilityPtr(const Date& referenceDate, const Calendar& cal, BusinessDayConvention bdc, const Handle<Quote>& volatility, const DayCounter& dc){ return new ConstantSwaptionVolatilityPtr( new ConstantSwaptionVolatility(referenceDate, cal, bdc, volatility, dc)); } ConstantSwaptionVolatilityPtr(Natural settlementDays, const Calendar& cal, BusinessDayConvention bdc, Volatility volatility, const DayCounter& dc){ return new ConstantSwaptionVolatilityPtr( new ConstantSwaptionVolatility(settlementDays, cal, bdc,volatility, dc)); } ConstantSwaptionVolatilityPtr(const Date& referenceDate, const Calendar& cal, BusinessDayConvention bdc, Volatility volatility, const DayCounter& dc){ return new ConstantSwaptionVolatilityPtr( new ConstantSwaptionVolatility(referenceDate, cal, bdc, volatility, dc)); } } }; Any help to address the floating bond coupon pricer issuer would be appreciated and I would resumit the code once everything is working. Lluís. ------------------------------------------------------------------------------ Get a FREE DOWNLOAD! and learn more about uberSVN rich system, user administration capabilities and model configuration. Take the hassle out of deploying and managing Subversion and the tools developers use with it. http://p.sf.net/sfu/wandisco-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users assetswap.rar (15K) Download Attachment |
Hi Lluis, I'll add your interfaces to the repository (and have a look at the error) when I get back from my vacations. Thanks for the contribution, Luigi On Fri, 2011-08-12 at 12:07 +0200, LLUIS PUJOL BAJADOR wrote: > I've been working for a quite long time (when some spare time is > available) to learn how to use the Quantlib library with Bonds using > Python. > After some other previous posts (Python bond example and Python CMS > test) I've been working to port the assetswap test to Python in order > to get a better understanding > on Quantlib/Bonds, SWIG and Python together. > > Please find attached the Assetswap test port to Python. It works quite > well with the exception of the following issue that I cannot figure > out how to solve. > > The real problem is on the floating bond coupon pricer that I get an > error when instantiated from the generic Bond (it works well for the > specialized constructor). See the following code and the exception: > > ## FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13) > ## maturity doesn't occur on a business day > floatingBondStartDate1 = Date(29,September,2003) > floatingBondMaturityDate1 = Date(29,September,2013) > floatingBondSchedule1 = Schedule(floatingBondStartDate1, > floatingBondMaturityDate1, > Period(Semiannual), > bondCalendar, > Unadjusted, Unadjusted, > DateGeneration.Backward, False) > floatingBondLeg1 = > list(IborLeg([self.faceAmount],floatingBondSchedule1, self.iborIndex, > > Actual360(),Following,[fixingDays],[],[0.0056],[inArrears])) > floatingbondRedemption1 = > bondCalendar.adjust(floatingBondMaturityDate1, Following) > floatingBondLeg1.append(SimpleCashFlow(100.0, > floatingbondRedemption1)) > ## generic bond > floatingBond1 = Bond(settlementDays, bondCalendar, > self.faceAmount, > floatingBondMaturityDate1, floatingBondStartDate1, > floatingBondLeg1) > floatingBond1.setPricingEngine(bondEngine) > > ## equivalent specialized floater > floatingSpecializedBond1 = FloatingRateBond(settlementDays, > self.faceAmount, > floatingBondSchedule1, > self.iborIndex, Actual360(), > Following, fixingDays, > [1], > [0.0056], > [], [], > inArrears, > 100.0, Date(29,September,2003)) > floatingSpecializedBond1.setPricingEngine(bondEngine) > > setCouponPricer(floatingBond1.cashflows(), self.pricer) > setCouponPricer(floatingSpecializedBond1.cashflows(), > self.pricer) > self.iborIndex.addFixing(Date(27,March,2007), 0.0402) > > > floatingBondTheoValue1 = floatingBond1.cleanPrice() ## The > error is raised here!! > floatingSpecializedBondTheoValue1 = > floatingSpecializedBond1.cleanPrice() ## This works well. > > > The exception is the following: > > ====================================================================== > ERROR: Testing clean and dirty prices for specialized bond against > equivalent generic bond... > ---------------------------------------------------------------------- > Traceback (most recent call last): > File "C:\Quantlib-SWIG\Python\test\assetswap.py", line 2541, in > testSpecializedBondVsGenericBond > floatingBondTheoValue1 = floatingBond1.cleanPrice() > File "C:\Python26\lib\site-packages\QuantLib\QuantLib.py", line > 6505, in cleanPrice > def cleanPrice(self, *args): return > _QuantLib.Bond_cleanPrice(self, *args) > RuntimeError: missing optionlet volatility > > The same error arise in some of the tests. (The code is Commented) > > > In order to get it working I had to add the following interface (just > let me know if I miss something and I will repost). > > In bonds.i > > I added the Bond Generic constructor: > public: > %extend { > BondPtr(Natural settlementDays, > const Calendar& calendar, > Real faceAmount, > const Date& maturityDate, > const Date& issueDate = Date(), > const Leg& cashflows = Leg()) { > return new BondPtr( > new Bond(settlementDays, > calendar, > faceAmount, > maturityDate, > issueDate, > cashflows)); > }; > > It is also needed the CMS Rate Bond constructor that is missin in the > current Trunk. > %{ > using QuantLib::CmsRateBond; > typedef boost::shared_ptr<Instrument> CmsRateBondPtr; > }% > > %rename(CmsRateBond) CmsRateBondPtr; > class CmsRateBondPtr : public BondPtr { > %feature("kwargs") CmsRateBondPtr; > public: > %extend { > CmsRateBondPtr(Size settlementDays, > Real faceAmount, > const Schedule& schedule, > const SwapIndexPtr& index, > const DayCounter& paymentDayCounter, > BusinessDayConvention paymentConvention, > Natural fixingDays , > const std::vector<Real>& gearings , > const std::vector<Spread>& spreads , > const std::vector<Rate>& caps , > const std::vector<Rate>& floors, > bool inArrears = false, > Real redemption = 100.0, > const Date& issueDate = Date()){ > boost::shared_ptr<SwapIndex> swap = > boost::dynamic_pointer_cast<SwapIndex>(index); > return new CmsRateBondPtr( > new CmsRateBond(settlementDays, > faceAmount, > schedule, > swap, > paymentDayCounter, > paymentConvention, > fixingDays, > gearings, > spreads, > caps, > floors, > inArrears, > redemption, > issueDate)); > } > } > }; > > > In the cashflows.i you need to include the interfaces included in a > previous posts around CMS Bonds. > > In the swap.i I add the assetswap constructor: > > %{ > using QuantLib::AssetSwap; > typedef boost::shared_ptr<Instrument> AssetSwapPtr; > }% > > %rename(AssetSwap) AssetSwapPtr; > class AssetSwapPtr : public SwapPtr { > public: > %extend { > AssetSwapPtr(bool payFixedRate, > const boost::shared_ptr<Instrument>& bond, > Real bondCleanPrice, > InterestRateIndexPtr& index, > Spread spread, > const Schedule& floatSchedule = Schedule(), > const DayCounter& floatingDayCount = DayCounter(), > bool parAssetSwap = true){ > const boost::shared_ptr<Bond> bo = > boost::dynamic_pointer_cast<Bond>(bond); > const boost::shared_ptr<IborIndex> iri = > boost::dynamic_pointer_cast<IborIndex>(index); > return new AssetSwapPtr( > new AssetSwap(payFixedRate,bo,bondCleanPrice, > iri,spread, floatSchedule, > floatingDayCount,parAssetSwap)); > } > > Real fairCleanPrice() { > return boost::dynamic_pointer_cast<AssetSwap>(*self) > ->fairCleanPrice(); > } > Spread fairSpread() { > return boost::dynamic_pointer_cast<AssetSwap>(*self) > ->fairSpread(); > } > } > }; > > > In addition I ammended the DiscountingEngine to include the > settlementflows. (it may breach some existing code so it may make > sense to overload it). > > %extend { > DiscountingSwapEnginePtr( > const Handle<YieldTermStructure>& > discountCurve, > bool includeSettlementDateFlows, > const Date& settlementDate = Date(), > const Date& npvDate = Date()) { > return new DiscountingSwapEnginePtr( > new > DiscountingSwapEngine(discountCurve, > > includeSettlementDateFlows, > > settlementDate, > > npvDate)); > } > } > > > In volatilities.i I added the following: > > // constant swaption term structure > > %{ > using QuantLib::ConstantSwaptionVolatility; > typedef boost::shared_ptr<SwaptionVolatilityStructure> > ConstantSwaptionVolatilityPtr; > %} > > %rename(ConstantSwaptionVolatility) ConstantSwaptionVolatilityPtr; > > class ConstantSwaptionVolatilityPtr > : public boost::shared_ptr<SwaptionVolatilityStructure> { > public: > %extend { > ConstantSwaptionVolatilityPtr(Natural settlementDays, > const Calendar& cal, > BusinessDayConvention bdc, > const Handle<Quote>& volatility, > const DayCounter& dc){ > return new ConstantSwaptionVolatilityPtr( > new ConstantSwaptionVolatility(settlementDays, cal, bdc, > volatility,dc)); > } > ConstantSwaptionVolatilityPtr(const Date& referenceDate, > const Calendar& cal, > BusinessDayConvention bdc, > const Handle<Quote>& volatility, > const DayCounter& dc){ > return new ConstantSwaptionVolatilityPtr( > new ConstantSwaptionVolatility(referenceDate, cal, bdc, > volatility, dc)); > } > ConstantSwaptionVolatilityPtr(Natural settlementDays, > const Calendar& cal, > BusinessDayConvention bdc, > Volatility volatility, > const DayCounter& dc){ > return new ConstantSwaptionVolatilityPtr( > new ConstantSwaptionVolatility(settlementDays, cal, > bdc,volatility, dc)); > } > ConstantSwaptionVolatilityPtr(const Date& referenceDate, > const Calendar& cal, > BusinessDayConvention bdc, > Volatility volatility, > const DayCounter& dc){ > return new ConstantSwaptionVolatilityPtr( > new ConstantSwaptionVolatility(referenceDate, cal, bdc, > volatility, dc)); > > } > > } > }; > > Any help to address the floating bond coupon pricer issuer would be > appreciated and I would resumit the code once everything is working. > > LluĆs. > ------------------------------------------------------------------------------ > Get a FREE DOWNLOAD! and learn more about uberSVN rich system, > user administration capabilities and model configuration. Take > the hassle out of deploying and managing Subversion and the > tools developers use with it. > http://p.sf.net/sfu/wandisco-dev2dev > _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users -- This gubblick contains many nonsklarkish English flutzpahs, but the overall pluggandisp can be glorked from context. -- David Moser ------------------------------------------------------------------------------ Get a FREE DOWNLOAD! and learn more about uberSVN rich system, user administration capabilities and model configuration. Take the hassle out of deploying and managing Subversion and the tools developers use with it. http://p.sf.net/sfu/wandisco-d2d-2 _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
In reply to this post by Lluis Pujol Bajador
On Fri, 2011-08-12 at 12:07 +0200, LLUIS PUJOL BAJADOR wrote:
> Please find attached the Assetswap test port to Python. It works quite > well with the exception of the following issue that I cannot figure > out how to solve. Lluis, you're initializing the IborLeg in the wrong way: > floatingBondLeg1 = > list(IborLeg([self.faceAmount],floatingBondSchedule1, self.iborIndex, > > Actual360(),Following,[fixingDays],[],[0.0056],[inArrears])) After [0.0056] for the spreads, you'll need to pass two more empty lists for caps and floors. Also, the boolear inArrears should not be inside a list, otherwise Python will convert the _list_ into a boolean (and since it's not empty, it will be true no matter what's inside.) The correct call is: IborLeg([self.faceAmount],floatingBondSchedule1, self.iborIndex, Actual360(),Following,[fixingDays],[],[0.0056],[],[],inArrears) I've added your modifications to the SWIG interface to the svn trunk, so if you check it out you should be able to build the Python module and run your tests against it. I've not added the tests to svn; please send them back to me when they work for you. Thanks, Luigi -- For every problem there is one solution which is simple, neat, and wrong. -- H. L. Mencken ------------------------------------------------------------------------------ Doing More with Less: The Next Generation Virtual Desktop What are the key obstacles that have prevented many mid-market businesses from deploying virtual desktops? How do next-generation virtual desktops provide companies an easier-to-deploy, easier-to-manage and more affordable virtual desktop model.http://www.accelacomm.com/jaw/sfnl/114/51426474/ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
El 12/09/2011 18:19, Luigi Ballabio escribiĆ³:
> On Fri, 2011-08-12 at 12:07 +0200, LLUIS PUJOL BAJADOR wrote: >> Please find attached the Assetswap test port to Python. It works quite >> well with the exception of the following issue that I cannot figure >> out how to solve. > Lluis, > you're initializing the IborLeg in the wrong way: > >> floatingBondLeg1 = >> list(IborLeg([self.faceAmount],floatingBondSchedule1, self.iborIndex, >> >> Actual360(),Following,[fixingDays],[],[0.0056],[inArrears])) I cannot believe I didn't figure it out. I reviewed all related Library code and I had it in front of my eyes. > After [0.0056] for the spreads, you'll need to pass two more empty lists > for caps and floors. Also, the boolear inArrears should not be inside a > list, otherwise Python will convert the _list_ into a boolean (and since > it's not empty, it will be true no matter what's inside.) The correct > call is: > > IborLeg([self.faceAmount],floatingBondSchedule1, self.iborIndex, > Actual360(),Following,[fixingDays],[],[0.0056],[],[],inArrears) > > I've added your modifications to the SWIG interface to the svn trunk, so > if you check it out you should be able to build the Python module and > run your tests against it. I've not added the tests to svn; please send > them back to me when they work for you. > > Thanks, > Luigi > > for me with the wrappers included in the trunk. Just a quick (and dumb) question. How do you format the text in order to fit with the required widht?. I mean I've looked at the cms.py test that I provided and you have reformatted it before including it in the trunk. Is there an "automated" way?. ------------------------------------------------------------------------------ All the data continuously generated in your IT infrastructure contains a definitive record of customers, application performance, security threats, fraudulent activity and more. Splunk takes this data and makes sense of it. Business sense. IT sense. Common sense. http://p.sf.net/sfu/splunk-d2d-oct _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users assetswap.rar (14K) Download Attachment |
On Tue, 2011-10-11 at 20:34 +0200, Lluis Pujol wrote:
> Please find attached an updated version with the errors solved. It works > for me with the wrappers included in the trunk. Ok, added. Thanks again. > Just a quick (and dumb) question. How do you format the text in order to > fit with the required widht?. > I mean I've looked at the cms.py test that I provided and you have > reformatted it before including it in the trunk. Is there an "automated" > way?. Not really. Having Emacs helps :) It's not a big problem, though. Sometimes I reformat the code when it gets difficult to follow in my emacs (which opens in 80 rows mode) but other times I just leave it alone. Luigi -- There's no sense in being precise when you don't even know what you're talking about. -- John von Neumann ------------------------------------------------------------------------------ The demand for IT networking professionals continues to grow, and the demand for specialized networking skills is growing even more rapidly. Take a complimentary Learning@Cisco Self-Assessment and learn about Cisco certifications, training, and career opportunities. http://p.sf.net/sfu/cisco-dev2dev _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Free forum by Nabble | Edit this page |