Hi
I'm trying to replicate a Swap price I can see on my Bloomberg page I 'm not using the Quantlib xl code, because some people in my company are not yet ready to use objects in Excel (pfff) => I have created my own interface with Excel Here is the code double vanillaSwapPrice(int todaysDate_, int tenorInYears, double fixRate, int forwardTenorInMonths, int fltFrequency_, xloper* yieldTermStructure, double nominal, char* type, int settlementDays, int fixFrequency_, char* calendar_, char* dayCounter_, char* fixDayCounter_, char* fltDayCounter_, double spread, char* results){ try{ QuantLib::Calendar calendar = toCalendar(calendar_, QuantLib::TARGET()); QuantLib::Calendar fixCalendar = calendar; QuantLib::Calendar fltCalendar = calendar; QuantLib::RelinkableHandle<QuantLib::YieldTermStructure> yTS; QuantLib::Frequency fixFrequency = toFrequency(fixFrequency_); QuantLib::Frequency fltFrequency = toFrequency(fltFrequency_, QuantLib::Semiannual); QuantLib::DayCounter dayCounter = toDayCounter(dayCounter_, QuantLib::Actual360()); QuantLib::DayCounter fixDayCounter = toDayCounter(fixDayCounter_, QuantLib::Thirty360(QuantLib::Thirty360::BondBasis)); QuantLib::DayCounter fltDayCounter = toDayCounter(fltDayCounter_, QuantLib::Actual360()); boost::shared_ptr<QuantLib::IborIndex> index = makeIborIndex(QuantLib::Period(fltFrequency),yTS) .withSettlementDays(settlementDays) .withCalendar(calendar) .withDayCounter(fltDayCounter); QuantLib::Date todaysDate = toDate(todaysDate_); QuantLib::Settings::instance().evaluationDate() = todaysDate; QuantLib::Date settlement = calendar.advance(todaysDate,settlementDays,QuantLib::Days); yTS.linkTo(toYieldTermStructure(settlement, calendar, dayCounter, yieldTermStructure)); QuantLib::VanillaSwap::Type typ; std::string type_ = std::string(type); if (type_ == "R") typ = QuantLib::VanillaSwap::Receiver; else if (type_ == "P") typ = QuantLib::VanillaSwap::Payer; else throw (std::string("unknwown type of Swap")); if (nominal ==0.0) nominal = 1.0; boost::shared_ptr<QuantLib::VanillaSwap> sw = makeVSwap(QuantLib::Period(tenorInYears,QuantLib::Years), index, fixRate, QuantLib::Period(forwardTenorInMonths,QuantLib::Months)) .withType(typ) .withNominal(nominal) .withFixedLegTenor(QuantLib::Period(fixFrequency)) .withFixedLegCalendar(fixCalendar) .withFixedLegDayCount(fixDayCounter) .withFloatingLegTenor(QuantLib::Period(fltFrequency)) .withFloatingLegSpread(QuantLib::Spread(spread)) .withFloatingLegCalendar(fltCalendar) .withFloatingLegDayCount(fltDayCounter); //Depending on what I want as results i can choose between return sw->NPV(); //return sw->fixedLegNPV(); //return sw->fixedLegBPS(); //return sw->floatingLegNPV(); //return sw->floatingLegBPS(); //return sw->fairRate(); } catch (...) { errMsg += "[" + functionCall->functionName() + "]" + "Unknown Error"; } //not the real return but adapted here to say somthg :-/ return -1; } The toXXX functions (i.e. toFrequency, toDayCounter, etc) are converter of the inputs into QuantLib types. The (optionnal) second input is the default value, if the first value is not right Here is the toYieldTermStructure function boost::shared_ptr<YieldTermStructure> toYieldTermStructure (Date settlement, Calendar calendar, DayCounter dayCounter, xloper* input, Compounding comp= QuantLib::Continuous, Frequency freq== QuantLib::Annual, bool endOfMonth= true){ std::vector<std::vector<double> >m = ObjectHandler::operToMatrix<double>(*input ,"Input"); unsigned int rows, cols, sizeInput; rows = m.size(); cols = m[0].size(); sizeInput = __max(rows,cols); boost::shared_ptr<YieldTermStructure> curve; if (sizeInput==1) curve = boost::shared_ptr<YieldTermStructure>( new FlatForward(settlement, m[0][0], dayCounter, comp, freq)); else{ std::vector<Date> vDate; std::vector<Real> vPrice; bool isDate = (m[0][0] >=367); //the first X-value of the curve is greater than 1/1/1901 => it's a date if (rows ==2 && cols > 2){ //horizontal data int j_init = 0; if (m[1][0] != 1.0){ vDate.push_back(settlement); vPrice.push_back(1.0); j_init++; } else { if ((isDate && toDate((long)m[0][0]) != settlement) || (!isDate && m[0][0] != 0.0)) throw (std::string("[toYieldTermStructure] Invalid first term value")); } for (unsigned int j = j_init; j< cols; j++){ if (isDate) vDate.push_back(toDate((long)m[0][j])); else //It is not a date => we assume the value is in Months and we add it to the settlement vDate.push_back(calendar.advance(settlement, (long)m[0][j], Months, QuantLib::Unadjusted, endOfMonth)); vPrice.push_back(m[1][j]); } } else if (cols ==2 && rows > 2){ //vertical data int i_init = 0; if (m[0][1] != 1.0){ vDate.push_back(settlement); vPrice.push_back(1.0); i_init ++; } else { if ((isDate && toDate((long)m[0][0]) != settlement) || (!isDate && m[0][0] != 0.0)) throw (std::string("[toYieldTermStructure] Invalid first term value")); } for (unsigned int i = i_init; i< rows; i++){ if (isDate) vDate.push_back(toDate((long)m[i][0])); else //It is not a date => we assume the value is in Months and we add it to the settlement vDate.push_back(calendar.advance(settlement, (long)m[i][0], Months, QuantLib::Unadjusted, endOfMonth)); vPrice.push_back(m[i][1]); } } else throw (std::string("[toYieldTermStructure] data has too much either cols or rows")); curve = boost::shared_ptr<YieldTermStructure>( new InterpolatedDiscountCurve<Cubic>( vDate, vPrice, dayCounter, calendar, Cubic(CubicInterpolation::Spline, false, CubicInterpolation::SecondDerivative, 0.0, CubicInterpolation::SecondDerivative, 0.0))); } return curve; } Finally in attach you can find the makeVSwap and makeIborIndex classes When I enter in Excel as inputs: int todaysDate_ = 40261 (ie 24/3/2010) int tenorInYears = 5 double fixRate = 2.21207% int forwardTenorInMonths = 0 int fltFrequency_ = 2 xloper* yieldTermStructure = the curve given by the the second gif file double nominal = 10000000 char* type = R int settlementDays = 0 int fixFrequency_ = 1 char* calendar_ = TARGET char* dayCounter_ =THIRTY360 char* fixDayCounter_ = THIRTY360 char* fltDayCounter_ = ACTUAL360 double spread = 0 it returns a value for NPV = -9252218 FixLegNPV = 1042594.49 FixLegBps = 4713.22 FltLegNPV = -1135118.66 FltLegBps = -4809.48 FairRate = 2.40837 Here are the questions Why do I have differences with Bloomberg. Is QuantLib coherent with Blmbg? Why the market value of each leg is so different (Blmg vs QuantLib)? (example QuantLIb FixLegNPV = 1042596.49 and Blmbg FixLegNPV = 9904395.99) Tks David QL_Blmbg.zip |
Free forum by Nabble | Edit this page |