ISDA CDS Model Phase One C++ interface

This is the example shipped with version 1.7 of the ISDA CDS model ported to our C++ interface Phase I:

// Copyright (C) 2009 International Swaps and Derivatives Association, Inc.
// Copyright (C) 2009 Bojan Nikolic <bojan@bnikolic.co.uk>
//
// LICENSE TERMS
//
// Licensed for on-screen viewing on your computer only. Distribution
// prohibited. This file is provided "as-is", without warranty of any
// kind, either expressed or implied, including, without limitation,
// warranties that the documentation is free of defects, merchantable,
// fit for a particular purpose or non-infringing. the entire risk as
// to the quality of the documentation is with you. Should this file
// prove defective in any respect, you (not the licensor) assume the
// cost of any necessary correction. This disclaimer of warranty
// constitutes an essential part of this license.
//
// In part derived from ISDA CDS Standard Model version 1.7
// You gen the copy of the original code at:
// http://www.bnikolic.co.uk/cds.html

#include <iostream>
#include <vector>

#include <boost/assign/list_of.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/format.hpp>
#include <boost/array.hpp>

#include "isda/cxzerocurve.h"
#include "isda/date_sup.h"
#include "isda/busday.h"
#include "isda/ldate.h"

#include "bncds/compat.hpp"
#include "bncds/stringcnv.hpp"
#include "bncds/convert.hpp"
#include "bncds/datehandle.hpp"
#include "bncds/ircurve.hpp"
#include "bncds/cds.hpp"


TCurve* BuildExampleZeroCurve()
{
  std::vector<char> types=boost::assign::list_of
    ('M')('M')('M')('M')('M')
    ('S')('S')('S')('S')('S')('S')('S')('S')('S');

  std::vector<std::string> expiries=boost::assign::list_of
    ("1M")("2M")("3M")("6M")("9M")
    ("1Y")("2Y")("3Y")("4Y")("5Y")("6Y")("7Y")("8Y")("9Y");

  std::vector<double> rates(14,1e-9);

  const char        badDayConv    ('M');
  const std::string holidays      ("None");
  const TDate       baseDate      (JpmcdsDate(2008, 1, 3));
  const long        mmDCC         (BNCDS::dayCC("Act/360"));
  const long        dcc           (BNCDS::dayCC("30/360"));

  TDateInterval ivl;
  BNCDS::dayIntrvl("6M", ivl);

  const double      freq           (BNCDS::frequency(ivl));

  const size_t n  = types.size();
  std::vector<TDate> dates(n);

  for (size_t i = 0; i<n; ++i)
  {
    TDateInterval tmp;
    BNCDS::dayIntrvl(expiries[i], tmp);

    dates[i]=BNCDS::ForwardNAdjust(baseDate,
                                   tmp,
                                   JPMCDS_BAD_DAY_NONE,
                                   "None");
  }

  std::cout<<"calling JpmcdsBuildIRZeroCurve..."
           <<std::endl;


  TCurve *zc=BNCDS::mkZeroCurve(baseDate,
                                types,
                                dates,
                                rates,
                                mmDCC,
                                (long)freq,
                                (long)freq,
                                dcc,
                                dcc,
                                badDayConv,
                                holidays);

  return zc;
}


/*

 Calculate upfront charge.

*/
double CalcUpfrontCharge(TCurve* curve,
                         double couponRate)
{
    TBoolean      payAccOnDefault = TRUE;
    double        parSpread = 3600;
    double        recoveryRate = 0.4;
    TBoolean      isPriceClean = FALSE;
    double        notional = 1e7;
    double        result = -1.0;


    const TDate today          = JpmcdsDate(2008, 2, 1);
    const TDate valueDate      = JpmcdsDate(2008, 2, 1);
    const TDate benchmarkStart = JpmcdsDate(2008, 2, 2);
    const TDate startDate      = JpmcdsDate(2008, 2, 8);
    const TDate endDate        = JpmcdsDate(2008, 2, 12);
    const TDate stepinDate     = JpmcdsDate(2008, 2, 9);

    const long dcc             = BNCDS::dayCC("Act/360");

    TDateInterval ivl;           BNCDS::dayIntrvl("1S", ivl);

    TStubMethod   stub;
    BNCDS::stubMethod("f/s",
                      stub);

    result=BNCDS::upfrontChrg(today,
                              valueDate,
                              benchmarkStart,
                              stepinDate,
                              startDate,
                              endDate,
                              couponRate / 10000.0,
                              payAccOnDefault,
                              ivl,
                              stub,
                              dcc,
                              'F',
                              "None",
                              *curve,
                              parSpread / 10000.0,
                              recoveryRate,
                              isPriceClean);

    return result * notional;
}


int main(int argc,
         char** argv)
{

  std::cout<<"building zero curve..."
           <<std::endl;
  boost::scoped_ptr<TCurve> zerocurve(BuildExampleZeroCurve());



  /* get discount factor */
  std::cout<<std::endl
           <<boost::format("Discount factor on 3rd Jan 08 = %f")  % JpmcdsZeroPrice(zerocurve.get(),
                                                                                    JpmcdsDate(2008,1,3))
           <<std::endl
           <<boost::format("Discount factor on 3rd Jan 09 = %f")  % JpmcdsZeroPrice(zerocurve.get(),
                                                                                    JpmcdsDate(2009,1,3))
           <<std::endl
           <<boost::format("Discount factor on 3rd Jan 17 = %f")  % JpmcdsZeroPrice(zerocurve.get(),
                                                                                    JpmcdsDate(2017,1,3))
           <<std::endl;


  boost::array<double,3> coupons = { { 0, 3600, 7200 } };

  for (size_t i=0; i < coupons.size(); ++i)
  {
    const double charge = CalcUpfrontCharge(zerocurve.get(),
                                            coupons[i]);
    std::cout<<std::endl
             <<boost::format("Upfront charge @ cpn = %ibps    =  %f") % coupons[i] % charge;
  }
  std::cout<<std::endl<<std::endl;


  return 0;
}