2011-03-07 15 views
15

birileri Excel/OpenOffice YIELD ve QuantLib kullanılarak PRICE işlevlerini çoğaltmak için nasıl bir örnek verebilir misiniz?QuantLib OpenOffice/Excel VERİM/FİYAT fonksiyonları

Birkaç örneğim var ancak henüz tüm kurulumu tam olarak anlamadım. Bazı değerleri değiştirmeye çalıştığımda sıfırları veya bazı saçma değerleri alıyorum. İdeal olarak YIELD/PRICE işlevlerine C++ eşdeğerini oluşturmak istiyorum.

İlk adımda, Excel tarih modellemesinde kusurları çoğaltmaya ihtiyacım yok. Tam bir çoğaltma yapmak için daha sonra bekleyebilirim. Yine de bunun nasıl harika olduğunu biliyor olsan da. OpenOffice içinde


PRICE örnek:

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

Benim QuantLib kod biraz kapalı 95.066759 alma yeteneğine sahiptir. En azından temel fiyat fonksiyonuna sahibim, sonuçlar için tam bir eşleşme elde etmek istiyorum.


Tüm paketleme kodunu kolayca ekleyemem ancak temel kod aşağıdaki gibidir. Eğer OpenOffice içinde PRICE fonksiyonun uygulanması ile ilgileniyorsanız

#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

Bu, kayan nokta türleriyle sayısal kararsızlık veya yuvarlama sorununun göstergesidir. Bir gmp multiprecision türü kullanarak hesaplamalarınızı yapmayı deneyin. Ayrıca, finansal tarih sayımının birçok varyasyonu olduğunu unutmayın, belki de oo sürümü quantlib'de bulunandan farklıdır. –

+0

Fark, kayan nokta hatası olacağından emin olmadığım kadar yüksek. Yine de gün tezgahında tek bir gün farkı olmamak için yeterince düşük. OO kodunu inceledim ve zaman zaman/sorgulanabilir/ancak tam olarak Excel ile ilişkilidir. QuantLib'e daha çok güveniyorum, ama aynı sonuçları üreten bir konfigürasyona sahip olmak çok güzel olurdu. –

+0

, C++ kodunuzu ekleyebilir misiniz? –

cevap

1

, sen AnalysisAddIn::getPrice uygulanmasında kodunu görebilirsiniz. Bu, analysis helper.cxx'daki getPrice_ işlevine başvurur. Belki orada neler olduğunu öğrenirsiniz.

Not, OpenGrok'un burada yanlış yapılandırılmış gibi göründüğünden, işlevlere tıklamak işe yaramayabilir. Ama sanırım /OOO340_m0/scaddins/source/analysis dizinindeki dosyalarda ihtiyacınız olan her şeyi bulabilirsiniz.