17

誰かがQuantLibYIELDを使用して Excel/OpenOfficeとPRICE関数を複製する方法の例を提供できますか?

いくつかの例がありますが、まだすべてのセットアップを完全に理解していません。いくつかの値を変更しようとすると、ゼロになるか、無意味な値になります。理想的には、YIELD/PRICE 関数に相当する C++ を作成したいと考えています。

最初のステップでは、Excel の日付モデリングの欠陥を再現する必要はありません。後で正確な複製を作成するまで待つことができます。あなたがその方法を知っていれば、それも素晴らしいことです。


PRICEたとえば、OpenOffice では次のようになります。

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

私の QuantLib コードは、95.066759どちらが少しずれているかを取得できます。少なくとも私は基本的な価格関数を持っています。今すぐ結果を正確に一致させたいと思います。


すべてのラッピング コードを簡単に含めることはできませんが、重要なコードは次のとおりです。

#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

1 に答える 1

2

PRICEOpenOffice での関数の実装に興味がある場合は、 AnalysisAddIn::getPriceの実装でコードを確認できます。これは、 のgetPrice_関数を参照しanalysis helper.cxxます。そこで何が起きているかわかるかもしれません。

ここでは OpenGrok の設定が間違っているように見えるため、機能をクリックしても機能しない可能性があることに注意してください。しかし、必要なものはすべて/OOO340_m0/scaddins/source/analysisディレクトリ内のファイルにあると思います。

于 2011-09-28T21:21:22.673 に答える