2011-03-07 23 views
15

Puede alguien dar un ejemplo de cómo replicar el Excel/OpenOffice YIELD y PRICE funciones utilizando QuantLib?funciones QuantLib OpenOffice/Excel RENDIMIENTO/PRECIO

Tengo algunos ejemplos pero todavía no entiendo toda la configuración. Cuando trato de cambiar algunos valores, obtengo ceros o algunos valores sin sentido. Idealmente, me gustaría crear el C++ equivalente a las funciones RENDIMIENTO/PRECIO.

En mi primer paso no necesito replicar los defectos en el modelado de fechas de Excel. Puedo esperar hasta más tarde para producir un duplicado exacto. Aunque si sabes cómo eso también es genial.


PRICE ejemplo, en OpenOffice:

PRICE("2008-02-15","2010-11-15",5%,7%,100,2,1) = 95.068419616675 

código Mi QuantLib es capaz de conseguir 95.066759 que es un poco apagado. Al menos tengo la función de precio básico, me gustaría obtener una coincidencia exacta para los resultados ahora.


No puedo incluir fácilmente todo el código de envoltura, pero el código esencial es el siguiente.

#include <ql/time/calendar.hpp> 
#include <ql/time/daycounters/actualactual.hpp> 
#include <ql/time/daycounters/actual365fixed.hpp> 
#include <ql/time/schedule.hpp> 
#include <ql/time/calendars/unitedstates.hpp> 
#include <ql/time/calendars/nullcalendar.hpp> 

#include <ql/settings.hpp> 
#include <ql/handle.hpp> 
#include <ql/termstructures/yield/flatforward.hpp> 
#include <ql/instruments/bonds/fixedratebond.hpp> 

#include <ql/pricingengines/bond/discountingbondengine.hpp> 
#include <ql/utilities/dataformatters.hpp> 

#include <iostream> 
#include <iomanip> 

#include "boost/date_time/gregorian/gregorian.hpp" 
using namespace QuantLib; 

Date convert_date(boost::gregorian::date const & date) 
{ 
    unsigned mon = date.month(); 
    return Date(date.day(), Month(mon), date.year()); 
} 

shared_ptr<Bond> create_bond(boost::gregorian::date const & settlement_, boost::gregorian::date const & maturity_, 
    double coupon_, double yield_, double redemption_, unsigned frequency_) 
{ 
    // date set up 
    //Calendar calendar = UnitedStates(UnitedStates::GovernmentBond); 
    Calendar calendar = NullCalendar(); //small improvement 

    Date settlementDate(convert_date(settlement_)); 
    // the settlement date must be a business day 
    settlementDate = calendar.adjust(settlementDate); 

    Integer fixingDays = 0; //1; 
    Natural settlementDays = 0; //1 

    Date evalDate = calendar.advance(settlementDate, -fixingDays, Days); 
    // Evaluation date (TODO: What should this actually be?) 
    Settings::instance().evaluationDate() = evalDate; 

    // bond set up 
    Real faceAmount = 100; 
    Real redemption = redemption_; 
    Date issueDate(1, January, 2001); //NOTE: shouldn't be relevant for price/yield calculations 
    Date maturity(convert_date(maturity_)); 
    Real couponRate = coupon_; 
    Real yield = yield_; 

    //ActualActual dayCounter(ActualActual::Bond); 
    ActualActual dayCounter; 
    //Actual365Fixed dayCounter; 

    RelinkableHandle<YieldTermStructure> discountingTermStructure; 
    boost::shared_ptr<YieldTermStructure> flatTermStructure(
     new FlatForward(
      settlementDate, 
      yield, 
      dayCounter, 
      Compounded, 
      Frequency(frequency_))); 
    discountingTermStructure.linkTo(flatTermStructure); 

    boost::shared_ptr<PricingEngine> bondEngine(
     new DiscountingBondEngine(discountingTermStructure)); 

    Schedule fixedBondSchedule(
     issueDate, 
     maturity, 
     Period(Frequency(frequency_)), 
     calendar, 
     Unadjusted, 
     Unadjusted, 
     DateGeneration::Backward, 
     false /*EOM*/); //strangely makes no difference in our calculations 

    boost::shared_ptr<Bond> fixedRateBond(new FixedRateBond(
     settlementDays, 
     faceAmount, 
     fixedBondSchedule, 
     std::vector<Rate>(1, couponRate), 
     dayCounter, 
     Unadjusted, 
     redemption)); 

    fixedRateBond->setPricingEngine(bondEngine); 
    return fixedRateBond; 
} 

//OpenOffice: PRICE("2008-02-15","2010-11-15",5%,7%,100,2,1) 
double bond_price(boost::gregorian::date const & settlement_, boost::gregorian::date const & maturity_, 
    double coupon_, double yield_, double redemption_, unsigned frequency_) 
{ 
    shared_ptr<Bond> bond(create_bond(settlement_, maturity_, coupon_, yield_, redemption_, frequency_)); 
    return bond->cleanPrice(); 
} 

//OpenOffice: PRICE("2008-02-15","2010-11-15",5%,7%,100,2,1) 
double bond_yield(boost::gregorian::date const & settlement_, boost::gregorian::date const & maturity_, 
    double coupon_, double price_, double redemption_, unsigned frequency_) 
{ 
    shared_ptr<Bond> bond(create_bond(settlement_, maturity_, coupon_, 0, redemption_, frequency_)); 
    ActualActual dayCounter; 
    return bond->yield(price_, dayCounter, Compounded, Frequency(frequency_)); 
} 
+4

esto es indicativo de una inestabilidad numérica o un problema de redondeo con los tipos de coma flotante. intente realizar sus cálculos usando un tipo de multiplicidad de gmp. También tenga en cuenta que el conteo de fechas financieras tiene muchas variaciones, tal vez la versión oo es diferente a la disponible en quantlib. –

+0

La diferencia es lo suficientemente alta como para no estar seguro de que sea un error de punto flotante. Sin embargo, es lo suficientemente bajo como para no ser una diferencia de un solo día en el contador de día. He revisado el código OO y es/cuestionable/a veces, pero se correlaciona exactamente con Excel. Estoy más inclinado a confiar en QuantLib aquí, pero sería muy agradable tener una configuración que produzca los mismos resultados. –

+0

¿puedes agregar tu código de C++? –

Respuesta

1

Si usted está interesado en la implementación de la función PRICE en OpenOffice, se puede ver el código de la aplicación de AnalysisAddIn::getPrice. Esto se refiere a la función getPrice_ en analysis helper.cxx. Tal vez descubras lo que está pasando allí.

Tenga en cuenta que OpenGrok parece estar mal configurado aquí, por lo que hacer clic en las funciones puede no funcionar. Pero supongo que encontrará todo lo que necesita en los archivos en el directorio /OOO340_m0/scaddins/source/analysis.

Cuestiones relacionadas