Login  Register

C++ AssetSwap test port to Python

Posted by Lluis Pujol Bajador on Aug 12, 2011; 10:07am
URL: http://quantlib.414.s1.nabble.com/C-AssetSwap-test-port-to-Python-tp347.html

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