2011-03-07 4 views
15

QuantLib을 사용하여 Excel/OpenOffice YIELDPRICE 함수를 복제하는 방법에 대한 예제를 제공 할 수 있습니까?QuantLib OpenOffice/Excel YIELD/PRICE 함수

몇 가지 예가 있지만 아직 모든 설정을 아직 ​​이해하지 못했습니다. 일부 값을 변경하려고하면 0이 나오거나 무의미한 값이 생깁니다. 이상적으로 나는 YIELD/PRICE 함수와 동등한 C++를 만들고 싶습니다.

첫 번째 단계에서는 Excel 날짜 모델링의 결함을 복제 할 필요가 없습니다. 나중에 정확한 복제본을 만들 때까지 기다릴 수 있습니다. 비록 당신이 그것이 얼마나 위대한 지 알기는하지만. 오픈 오피스에서


PRICE 예 :

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

내 QuantLib 코드는 조금 꺼져 95.066759을 받고 할 수 있습니다. 적어도 기본적인 가격 기능을 가지고 있습니다. 결과에 대한 정확한 일치를 얻고 싶습니다.


나는 모든 래핑 코드를 쉽게 포함 할 수 없지만 필수 코드는 다음과 같습니다. 오픈 오피스에서 PRICE 함수의 구현에 관심이 있다면

#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

이것은 부동 소수점 유형에 대한 수치 적 불안정성 또는 반올림 문제를 나타냅니다. gmp 다중 정밀도 유형을 사용하여 계산을 수행하십시오. 또한 재무 날짜 계산에는 많은 변형이 있으며 oo 버전은 quantlib에서 사용할 수있는 버전과 다를 수 있습니다. –

+0

그 차이가 충분히 높아서 부동 소수점 오류가 될지 잘 모르겠습니다. 그러나 하루 카운터에서 하루 차이가 없을만큼 낮습니다. OO 코드를 살펴본 결과// 때때로/의심 스럽지만 Excel과 정확하게 관련됩니다. 나는 여기서 QuantLib을 신뢰할 의향이 있지만, 같은 결과를내는 설정을 갖는 것이 정말 좋을 것입니다. –

+0

C++ 코드를 추가 할 수 있습니까? –

답변

1

, 당신은 AnalysisAddIn::getPrice의 구현에 코드를 볼 수 있습니다. 이것은 getPrice_ 기능을 analysis helper.cxx에 나타냅니다. 어쩌면 거기에서 무슨 일이 일어나고 있는지 알 수 있습니다.

여기에서 OpenGrok이 잘못 구성되어있어 기능을 클릭해도 작동하지 않을 수 있습니다. 그러나 당신이 디렉토리 /OOO340_m0/scaddins/source/analysis에있는 파일들에서 필요한 모든 것을 찾았다 고 생각합니다.