Re: CMS Bonds in Python

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: CMS Bonds in Python

Lluis Pujol Bajador
Hi,

After some time playing with it I've been able to port most of the cms testsuite to Python. Please find it attached.

In order run it you need to update de interface file with the following changes below. I've checked the individual results and compared with the C++ version and match.

The only part I am not able to figure it out is how to create the MakeCms helper class interface (this is the reason for the failed third test) . A hint would be appreciated.
I would also appreaciate any comment if I am doing something wrong or not in the most correct/efficient way.

The changes in the interfaces I made are the following.


+ Include the following lines in the marketelements.i in order to handle vector of vectors of handles.
  
    %template(QuoteVVector) vector<vector<boost::shared_ptr<Quote> > >;
    %template(QuoteHandleVVector) vector<vector<Handle<Quote> > >;
    %template(RelinkableQuoteHandleVVector) vector<vector<RelinkableHandle<Quote> > >;

+ Include in vectors.i the following in order to be able to pass a vectors of bools to VolCube1 from a python list. (i don't have a clue but it works).

%template(BoolVector) vector<bool>;
   
    swigr_list_converter(BoolVector,
    _p_std__vectorTbool_std__allocatorTbool_t_t,
    boolean)

+ Add the following to volatilities.i

%include indexes.i
%include optimizers.i


SwaptionVolatilityMatrixPtr(const Calendar& calendar,
                                BusinessDayConvention bdc,
                                    const std::vector<Period>& optionTenors,
                                    const std::vector<Period>& swapTenors,
                                    const std::vector<std::vector<Handle<Quote> > >& vols,
                                    const DayCounter& dayCounter){
            return new SwaptionVolatilityMatrixPtr(
                new SwaptionVolatilityMatrix(calendar,bdc,optionTenors,swapTenors,vols,dayCounter));
      
         } 


    SwaptionVolatilityMatrixPtr(
                    const Calendar& calendar,
                    BusinessDayConvention bdc,
                    const std::vector<Period>& optionTenors,
                    const std::vector<Period>& swapTenors,
                    const Matrix& vols,
                    const DayCounter& dayCounter){
            return new SwaptionVolatilityMatrixPtr(
                new SwaptionVolatilityMatrix(calendar,bdc,optionTenors,swapTenors,vols,dayCounter));
         } 
    }
};

%{
using QuantLib::SwaptionVolCube2;
typedef boost::shared_ptr<SwaptionVolatilityStructure>
    SwaptionVolCube2Ptr;
%}

%rename(SwaptionVolCube2) SwaptionVolCube2Ptr;
class SwaptionVolCube2Ptr
    : public boost::shared_ptr<SwaptionVolatilityStructure> {
  public:
    %extend {
        SwaptionVolCube2Ptr(const Handle<SwaptionVolatilityStructure>& atmVolStructure,
                            const std::vector<Period>& optionTenors,
                            const std::vector<Period>& swapTenors,
                            const std::vector<Spread>& strikeSpreads,
                            const std::vector<std::vector<Handle<Quote> > >& volSpreads,
                            const SwapIndexPtr& swapIndexBase,
                        const SwapIndexPtr& shortSwapIndexBase,
                            bool vegaWeightedSmileFit) {
                        const boost::shared_ptr<SwapIndex> swi =
          boost::dynamic_pointer_cast<SwapIndex>(swapIndexBase);
                const boost::shared_ptr<SwapIndex> shortSwi =
          boost::dynamic_pointer_cast<SwapIndex>(shortSwapIndexBase);
            return new SwaptionVolCube2Ptr(
                new SwaptionVolCube2(atmVolStructure,optionTenors,swapTenors,strikeSpreads,
                    volSpreads, swi, shortSwi, vegaWeightedSmileFit));
        }
    }
};


%{
using QuantLib::SwaptionVolCube1;
typedef boost::shared_ptr<SwaptionVolatilityStructure> SwaptionVolCube1Ptr;
%}

%rename(SwaptionVolCube1) SwaptionVolCube1Ptr;
class SwaptionVolCube1Ptr
    : public boost::shared_ptr<SwaptionVolatilityStructure> {
  public:
    %extend {
    SwaptionVolCube1Ptr(const Handle<SwaptionVolatilityStructure>& atmVolStructure,
                        const std::vector<Period>& optionTenors,
                            const std::vector<Period>& swapTenors,
                            const std::vector<Spread>& strikeSpreads,
                            const std::vector<std::vector<Handle<Quote> > >& volSpreads,
                            const boost::shared_ptr<Index> swapIndexBase,
                            const boost::shared_ptr<Index> shortSwapIndexBase,
                            bool vegaWeightedSmileFit,
                            const std::vector<std::vector<Handle<Quote> > >& parametersGuess,
                            const std::vector<bool>& isParameterFixed,
                            bool isAtmCalibrated,
                            const boost::shared_ptr<EndCriteria>& endCriteria
                            = boost::shared_ptr<EndCriteria>(),
                            Real maxErrorTolerance = Null<Real>(),
                            const boost::shared_ptr<OptimizationMethod>& optMethod
                            = boost::shared_ptr<OptimizationMethod>()) {
                        const boost::shared_ptr<SwapIndex> swi =
          boost::dynamic_pointer_cast<SwapIndex>(swapIndexBase);
                const boost::shared_ptr<SwapIndex> shortSwi =
          boost::dynamic_pointer_cast<SwapIndex>(shortSwapIndexBase);
            return new SwaptionVolCube1Ptr(
                new SwaptionVolCube1(atmVolStructure,optionTenors,swapTenors,strikeSpreads,
                    volSpreads, swi, shortSwi, vegaWeightedSmileFit,
                    parametersGuess,isParameterFixed,isAtmCalibrated,
                    endCriteria,maxErrorTolerance,optMethod));
        }
    }
};

+ add the following to cashflows.i

* I needed the Coupon class in order to use accrualPeriod functions of this class in FloatingRateCoupon. (I don't know if it is the best way but it works)
using QuantLib::Coupon;

%ignore Coupon;
class Coupon : public CashFlow {
  public:
    Coupon(const Date& paymentDate,
               Real nominal,
               const Date& accrualStartDate,
               const Date& accrualEndDate,
               const Date& refPeriodStart = Date(),
               const Date& refPeriodEnd = Date());
};

%{
using QuantLib::CmsCoupon;
using QuantLib::CappedFlooredCoupon;
using QuantLib::CappedFlooredCmsCoupon;

typedef boost::shared_ptr<CashFlow> CouponPtr;
typedef boost::shared_ptr<CashFlow> CmsCouponPtr;
typedef boost::shared_ptr<CashFlow> CappedFlooredCouponPtr;
typedef boost::shared_ptr<CashFlow> CappedFlooredCmsCouponPtr;
%}

* Add the following function to FloatingRateCouponPtr:

        Time accrualPeriod() {
            return boost::dynamic_pointer_cast<FloatingRateCoupon>(*self)
                ->accrualPeriod();
        }

        Real price(const Handle<YieldTermStructure>& discountingCurve) const{
            return boost::dynamic_pointer_cast<FloatingRateCoupon>(*self)->price(discountingCurve);
        }


* Add CmsCoupon Class


%rename(CmsCoupon) CmsCouponPtr;
class CmsCouponPtr : public FloatingRateCouponPtr {
      public:
    %extend {
        CmsCouponPtr(const Date& paymentDate, Real nominal,
                  const Date& startDate, const Date& endDate,
                  Integer fixingDays, const boost::shared_ptr<SwapIndex>& index,
                  Real gearing = 1.0, Spread spread = 0.0,
                  const Date& refPeriodStart = Date(),
                  const Date& refPeriodEnd = Date(),
                  const DayCounter& dayCounter = DayCounter(),
                  bool isInArrears = false) {       
            const boost::shared_ptr<SwapIndex> swi =
          boost::dynamic_pointer_cast<SwapIndex>(index);
            return new CmsCouponPtr(
        new CmsCoupon(paymentDate,nominal,startDate,endDate,
                  fixingDays,swi,gearing,spread,
                  refPeriodStart, refPeriodEnd, dayCounter,isInArrears));
        }
   
     }   

};

* Add following pricers and GFunction needed:
%{

using QuantLib::FloatingRateCouponPricer;
using QuantLib::CmsCouponPricer;
using QuantLib::AnalyticHaganPricer;
using QuantLib::NumericHaganPricer;
using QuantLib::GFunction;
using QuantLib::GFunctionFactory;

typedef boost::shared_ptr<CmsCouponPricer> AnalyticHaganPricerPtr;
typedef boost::shared_ptr<CmsCouponPricer> NumericHaganPricerPtr;
%}

%ignore CmsCouponPricer;
class CmsCouponPricer {
  public:
    Handle<SwaptionVolatilityStructure> swaptionVolatility() const;
    void setSwaptionVolatility(const Handle<SwaptionVolatilityStructure>& v=
                                    Handle<SwaptionVolatilityStructure>());
};



%template(CmsCouponPricer) boost::shared_ptr<CmsCouponPricer>;
void setCouponPricer(const Leg&, const boost::shared_ptr<CmsCouponPricer>&);

class GFunctionFactory {
public:
        enum YieldCurveModel { Standard,
                               ExactYield,
                               ParallelShifts,
                               NonParallelShifts};
        static boost::shared_ptr<GFunction> newGFunctionStandard(Size q, Real delta, Size swapLength);
        static boost::shared_ptr<GFunction> newGFunctionExactYield(const CmsCoupon& coupon);
        static boost::shared_ptr<GFunction> newGFunctionWithShifts(const CmsCoupon& coupon, const Handle<Quote>& meanReversion);
private:
        GFunctionFactory();
};

%rename(AnalyticHaganPricer) AnalyticHaganPricerPtr;
class AnalyticHaganPricerPtr : public boost::shared_ptr<CmsCouponPricer> {
  public:
    %extend {
    AnalyticHaganPricerPtr(const Handle<SwaptionVolatilityStructure>& v,
               GFunctionFactory::YieldCurveModel model,
               const Handle<Quote>& meanReversion) {
            return new AnalyticHaganPricerPtr(new AnalyticHaganPricer(v, model, meanReversion));
    }
     }
};

%rename(NumericHaganPricer) NumericHaganPricerPtr;
class NumericHaganPricerPtr : public boost::shared_ptr<CmsCouponPricer> {
  public:
    %extend {
        NumericHaganPricerPtr(const Handle<SwaptionVolatilityStructure>& v,
                          GFunctionFactory::YieldCurveModel model,
                              const Handle<Quote>& meanReversion,
                              Rate lowerLimit = 0.0,
                              Rate upperLimit = 1.0,
                              Real precision = 1.0e-6) {
             return new NumericHaganPricerPtr(
        new NumericHaganPricer(v, model, meanReversion,lowerLimit,upperLimit,precision));
       
        }
    }
};




%rename(CappedFlooredCoupon) CappedFlooredCouponPtr;
class CappedFlooredCouponPtr : public FloatingRateCouponPtr {
      public:
    %extend {
        CappedFlooredCouponPtr(const boost::shared_ptr<FloatingRateCoupon>& underlying,
                  Rate cap = Null<Rate>(),
                  Rate floor = Null<Rate>()) {
        return new CappedFlooredCouponPtr(
                new CappedFlooredCoupon(underlying,cap,floor));
        }
        //Rate rate() const;
        Rate convexityAdjustment() {
            return boost::dynamic_pointer_cast<CappedFlooredCoupon>(*self)
                ->convexityAdjustment();
        }
        Rate cap() {
           return boost::dynamic_pointer_cast<CappedFlooredCoupon>(*self)
                ->cap();
        }
        Rate floor() {
           return boost::dynamic_pointer_cast<CappedFlooredCoupon>(*self)
                ->floor();
        }
        Rate effectiveCap() {
           return boost::dynamic_pointer_cast<CappedFlooredCoupon>(*self)
                ->effectiveCap();
        }
        Rate effectiveFloor() {
           return boost::dynamic_pointer_cast<CappedFlooredCoupon>(*self)
                ->effectiveFloor();
        }
        bool isCapped() {
           return boost::dynamic_pointer_cast<CappedFlooredCoupon>(*self)
                ->isCapped();
        }
        bool isFloored() {
           return boost::dynamic_pointer_cast<CappedFlooredCoupon>(*self)
                ->isFloored();
        }
        void setPricer(const boost::shared_ptr<CmsCouponPricer>& pricer){
            const boost::shared_ptr<FloatingRateCouponPricer> pri =
                boost::dynamic_pointer_cast<FloatingRateCouponPricer>(pricer);
            boost::dynamic_pointer_cast<CappedFlooredCoupon>(*self)->setPricer(pri);
        }
    }
};



%rename(CappedFlooredCmsCoupon) CappedFlooredCmsCouponPtr;
class CappedFlooredCmsCouponPtr: public CappedFlooredCouponPtr {
    public:
     
      %extend{
        CappedFlooredCmsCouponPtr(const Date& paymentDate,
                  Real nominal,
                  const Date& startDate,const Date& endDate,
                  Natural fixingDays, const SwapIndexPtr& index,
                  Real gearing = 1.0,Spread spread= 0.0,
                  const Rate cap = Null<Rate>(), const Rate floor = Null<Rate>(),
                  const Date& refPeriodStart = Date(), const Date& refPeriodEnd = Date(),
                  const DayCounter& dayCounter = DayCounter(), bool isInArrears = false) {
    const boost::shared_ptr<SwapIndex> swi =
                boost::dynamic_pointer_cast<SwapIndex>(index);
        return new CappedFlooredCmsCouponPtr(
        new CappedFlooredCmsCoupon(paymentDate, nominal, startDate, endDate, fixingDays,
                      swi, gearing, spread, cap, floor,refPeriodStart, refPeriodEnd, dayCounter, isInArrears));

    }
      
    }
};





On Thu 07/07/11 09:23 , Luigi Ballabio <[hidden email]> wrote:

On Wed, 2011-07-06 at 22:42 +0200, Lluis Pujol Bajador wrote:
> Thank Francis.
>
> It works.
>
> I had also to cast the SwapIndex to Index.

Lluis,
once you have a working version, just post it here and I'll be happy to
include it in the library.

Luigi


--

Brady's First Law of Problem Solving:
When confronted by a difficult problem, you can solve it more
easily by reducing it to the question, "How would the Lone
Ranger have handled this?"




------------------------------------------------------------------------------
AppSumo Presents a FREE Video for the SourceForge Community by Eric
Ries, the creator of the Lean Startup Methodology on "Lean Startup
Secrets Revealed." This video shows you how to validate your ideas,
optimize your ideas and identify your business strategy.
http://p.sf.net/sfu/appsumosfdev2dev
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users

cms.py (22K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: CMS Bonds in Python

Luigi Ballabio
On Sun, 2011-07-17 at 11:49 +0200, Lluis Pujol Bajador wrote:
> After some time playing with it I've been able to port most of the cms
> testsuite to Python. Please find it attached.
>
> In order run it you need to update de interface file with the
> following changes below.

Thanks, I'll add your code when I have some time.

> The only part I am not able to figure it out is how to create the
> MakeCms helper class interface (this is the reason for the failed
> third test) . A hint would be appreciated.

Hmm. It's a tricky one to export, since it uses a conversion operator
and doesn't map directly in the mapped languages.  I'd say we leave it
out for now.

Later,
        Luigi


--

I have yet to see any problem, however complicated, which, when you
looked at it in the right way, did not become still more complicated.
-- Poul Anderson



------------------------------------------------------------------------------
AppSumo Presents a FREE Video for the SourceForge Community by Eric
Ries, the creator of the Lean Startup Methodology on "Lean Startup
Secrets Revealed." This video shows you how to validate your ideas,
optimize your ideas and identify your business strategy.
http://p.sf.net/sfu/appsumosfdev2dev
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users