Функции QuantLib OpenOffice/Excel YIELD/PRICE
Может ли кто-нибудь предоставить пример того, как реплицировать функции Excel/OpenOffice YIELD
и PRICE
, используя QuantLib?
У меня есть несколько примеров, но я пока не совсем понимаю все настройки. Когда я пытаюсь изменить некоторые значения, я получаю нули или некоторые бессмысленные значения. В идеале я хотел бы создать эквивалент С++ для функций YIELD/PRICE.
На моем первом этапе мне не нужно копировать дефекты в модели даты в 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_) );
}
Ответы
Ответ 1
Если вы заинтересованы в реализации функции PRICE
в OpenOffice, вы можете увидеть код в реализации AnalysisAddIn:: getPrice. Это относится к функции getPrice_ в analysis helper.cxx
. Может быть, вы узнаете, что там происходит.
Обратите внимание, что OpenGrok, кажется, неправильно настроен здесь, поэтому нажатие на функции может не работать. Но я полагаю, вы найдете все, что вам нужно, в файлах в каталоге /OOO340_m0/scaddins/source/analysis.