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_));
}
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. –
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. –
, C++ kodunuzu ekleyebilir misiniz? –