2015-08-28 3 views
0

Я хотел бы получить шаблон класса из QuantLib :: PiecewiseYieldCurve. Это мое получено определение класса:C++: получить шаблон класса из QuantLib :: PiecewiseYieldCurve

#include <ql\termstructures\yield\piecewiseyieldcurve.hpp> 
#include <MarKetQuote\include\OISQuote.h> 
#include <vector> 

using namespace QuantLib; 

/*! \brief Class to bootstrap an OIS curve. 
*/ 
template <class Traits, class Interpolator, 
    template <class> class Bootstrap = IterativeBootstrap> 
class OISCurve : public PiecewiseYieldCurve < Traits, Interpolator, Bootstrap > 
{ 
private: 
    /** Typedef to refer to the specialized class. 
    It was necessary to add it in other to be able to declare the constructor as in QuantLib::PiecewiseYieldCurve. 
    */ 
    typedef OISCurve<Traits, Interpolator, Bootstrap> this_ois_curve; 
public: 
    /** Constructor. 
    */ 
    OISCurve(
     const Date& referenceDate, 
     const std::vector<OISQuote>& quotes, 
     const DayCounter& dayCounter, 
     Real accuracy, 
     const Interpolator& i = Interpolator(), 
     const Bootstrap<this_ois_curve>& bootstrap = Bootstrap<this_ois_curve>()); 
}; 

OISQuote просто класс, производный от QuantLib :: SimpleQuote. Я не знаком с этим сложным шаблоном, но, к моему ограниченному пониманию, это должно быть хорошо. Он компилируется на самом деле. Проблема возникает, когда я пытаюсь создать экземпляр специализированного класса, как это:

OISCurve<Discount, LogLinear> oisCurve = OISCurve<Discount, LogLinear>(Date::todaysDate(), quotes, Actual360(), 1.0e-12); 

Я получаю LNK2019 ошибки связывания (с помощью Visual Studio):

main.obj : error LNK2019: unresolved external symbol "public: __cdecl OISCurve<struct QuantLib::Discount,class QuantLib::LogLinear,class QuantLib::IterativeBootstrap>::OISCurve<struct QuantLib::Discount,class QuantLib::LogLinear,class QuantLib::IterativeBootstrap>(class QuantLib::Date const &,class std::vector<class OISQuote,class std::allocator<class OISQuote> > const &,class QuantLib::DayCounter const &,double,class QuantLib::LogLinear const &)" ([email protected]@[email protected]@[email protected]@[email protected]@@@[email protected]@[email protected]@[email protected]@@[email protected]@@@[email protected]@@[email protected]@[email protected]@[email protected]@@Z) referenced in function main 
1>C:\Users\u8998\PricingEngine\build\Debug\main.exe : fatal error LNK1120: 1 unresolved externals 

Спасибо за помощь.

EDIT:

Извините за поздний ответ. Спасибо @LuigiBallabio и @StudentT за ваши ответы. Моя проблема была вызвана моей неопытной работой с шаблонами классов. У меня было объявление в файле заголовка и моей реализации в файле cpp точно так же, как и в любом другом классе. Следуя указаниям в принятом ответе this question я изменил свой код соответственно:

OISCurve.h

#ifndef OIS_CURVE_H 
#define OIS_CURVE_H 

#include <ql\termstructures\yield\piecewiseyieldcurve.hpp> 
#include <ql\termstructures\yield\ratehelpers.hpp> 
#include <ql\quote.hpp> 
#include <vector> 
#include <boost\shared_ptr.hpp> 

using namespace QuantLib; 


template <class Traits, class Interpolator, 
    template <class> class Bootstrap = IterativeBootstrap> 
class OISCurve : public PiecewiseYieldCurve < Traits, Interpolator, Bootstrap > 
{ 
public: 

    OISCurve(const Date& referenceDate, 
     const std::vector<boost::shared_ptr<Quote>>& quotes, 
     const DayCounter& dayCounter, 
     Real accuracy); 

    friend std::vector<boost::shared_ptr<RateHelper>> getRateHelpers(const std::vector<boost::shared_ptr<Quote>>& quotes); 

private: 
    std::vector<boost::shared_ptr<Quote>> quotes_; 
}; 

#include <CurveBootstrapping\src\OISCurve.cpp> 

#endif 

OISCurve.cpp

#include "OISCurve.h" 
#include <ql\errors.hpp> 
#include <algorithm> 
#include <boost\foreach.hpp> 
#include <ql\termstructures\yield\oisratehelper.hpp> 
#include <MarKetQuote\include\OISQuote.h> 
#include <ql\handle.hpp> 
#include <ql\indexes\ibor\eonia.hpp> 

#ifndef OIS_CURVE_IMPL 
#define OIS_CURVE_IMPL 

template <class T, class I, template <class> class B> 
OISCurve<T, I, B>::OISCurve(
    const Date& referenceDate, 
    const std::vector<boost::shared_ptr<Quote>>& quotes, 
    const DayCounter& dayCounter, 
    Real accuracy) 
    : PiecewiseYieldCurve < T, I, B >(referenceDate, 
    initializeQuotesAndGetRateHelpers(quotes), 
    dayCounter, 
    accuracy) 
{ 
    std::cout << "constructor works" << std::endl; 
} 

std::vector<boost::shared_ptr<RateHelper>> getRateHelpers(const std::vector<boost::shared_ptr<Quote>>& quotes) 
{ 

    QL_REQUIRE(std::all_of(quotes.begin(), quotes.end(), [](boost::shared_ptr<Quote> quote){ return boost::dynamic_pointer_cast<OISQuote>(quote) != 0; }), 
     "All quotes must be OISQuotes!"); 

    std::vector<boost::shared_ptr<RateHelper>> rateHelpers; 
    BOOST_FOREACH(boost::shared_ptr<Quote> quote, quotes) 
    { 
     rateHelpers.push_back(boost::shared_ptr<RateHelper>(new OISRateHelper(2, 
      boost::dynamic_pointer_cast<OISQuote>(quote)->tenor(), 
      Handle<Quote>(quote), 
      boost::shared_ptr<OvernightIndex>(new Eonia())))); 
    } 

    return rateHelpers; 
} 

#endif 

Это решение я понравилось больше всего.

+0

Этот вопрос относится к обмену столов, поскольку его программирование связано. – chollida

+1

hmm quantlib - это самый большой проект кодирования с открытым исходным кодом для количественного финансирования, и вопрос заключается в том, как его использовать, поэтому я думаю, что он принадлежит больше на quant.stackexchange.com. –

ответ

1

Я не думаю, что эти вопросы касаются количественного финансирования вообще, но я все равно отвечу.

Вы не предоставили реализацию конструктору класса OISCurve.

Чтобы связать свою программу, сделайте следующее:

OISCurve(
    const Date& referenceDate, 
    const std::vector<OISQuote>& quotes, 
    const DayCounter& dayCounter, 
    Real accuracy, 
    const Interpolator& i = Interpolator(), 
    const Bootstrap<this_ois_curve>& bootstrap = Bootstrap<this_ois_curve>()) 
: <Call Parent Constructor> 
{ 

} 

Вам нужно будет заменить вызов фактического конструктора, определенное в PiecewiseYieldCurve. Есть шесть таких конструкторов, поэтому вам нужно выбрать тот, который вы считаете наиболее подходящим. Обратите внимание, что вам нужно будет предоставить родительскому конструктору список инструментов, но он отсутствует в определении конструктора.

+1

. Не будет легко собрать список необходимых помощников в список инициализации. В этом случае вместо наследования класса я бы пошел на функцию, которая берет необходимые входы, строит список помощников и возвращает экземпляр 'PiecewiseYieldCurve'. –

+0

@LuigiBallabio Да, согласен. Из приведенных выше определений довольно сложно построить класс PiecewiseYieldCurve. На самом деле, я думаю, что плакат смущен. Он должен только наследовать PiecewiseYieldCurve, если он хочет обеспечить лучшую стратегию самонастройки, но я не думаю, что это имеет место здесь. Ему просто нужен собственный способ построения кривой. – SmallChess

Смежные вопросы