#include <ql/quantlib.hpp>

#include <boost/timer.hpp>
#include <iostream>
#include <iomanip>

using namespace QuantLib;

#if defined(QL_ENABLE_SESSIONS)
namespace QuantLib {

Integer sessionId() { return 0; }

}
#endif


int main(int, char* []) {

    try {

         /////////////////////////////////////////////////////////////////////////////
		 /////////////////////////////////////////////////////////////////////////////
		 //    calculate Yield to maturity of Fixed Rate Bond
		 /////////////////////////////////////////////////////////////////////////////
		 /////////////////////////////////////////////////////////////////////////////
	 
		    /*
        boost::shared_ptr<FixedRateBond> bond(
                       new FixedRateBond(faceAmount,
                                         bondIssueDate,
                                         bondDatedDate,
                                         bondMaturityDate,
                                         bondSettlementDays,
                                         std::vector<Rate>(1,bondCoupon),
                                         bondCouponFrequency,
                                         bondCalendar,
                                         bondDayCountConvention,
                                         bondBusinessDayConvention,
                                         bondBusinessDayConvention,
                                         bondRedemption,
                                         bondCurve));
    
	*/
		 //////////BondSchedule Class Declarations//////////////////
		 Date bondDatedDate(15,June,2010);
		 Date SettlementDate(25,June,2011);
		 Date bondMaturityDate(15,June,2011);
		 Frequency bondCouponFrequency = Annual;
		 Calendar bondCalendar = NullCalendar();
		 BusinessDayConvention bondBusinessDayConvention = Unadjusted;
		 ////////////////////////////////////////////////////////////

		 //////////FixedRateBond Class Declarations//////////////////
		 Integer bondSettlementDays = 0;
		 Real faceAmount = 100.0;
		 Real bondCoupon = 5; //interest rate
		 DayCounter bondDayCountConvention = Thirty360(Thirty360::BondBasis);
		 Real bondRedemption = 10.0;
		 Date bondIssueDate(15,June,2010);
		 ////////////////////////////////////////////////////////////

		 Schedule bondSchedule(bondDatedDate, bondMaturityDate,
								Period(bondCouponFrequency),
								bondCalendar,bondBusinessDayConvention,
								bondBusinessDayConvention,
								DateGeneration::Forward,false);
		 
		 
	
		 boost::shared_ptr<FixedRateBond> bond(
			 new FixedRateBond  (bondSettlementDays,
								faceAmount,
								bondSchedule,
								std::vector<Rate>(1,bondCoupon),
								bondDayCountConvention,
								bondBusinessDayConvention,
								bondRedemption,
								bondIssueDate));




		 Real Clean_Price = 90;
		 		 
		 std::cout << "----\n";
		 


		 /*
		 RelinkableHandle<YieldTermStructure> bondCurve;
		 bondCurve.linkTo(boost::shared_ptr<YieldTermStructure>(
			 new FlatForward(SettlementDate,
			 bondCoupon, // interest rate
			 bondDayCountConvention,
			 Compounded,
			 bondCouponFrequency)));


		 bond->setPricingEngine(boost::shared_ptr<PricingEngine>(
			 new DiscountingBondEngine(bondCurve)));

		 bondCurve.linkTo(boost::shared_ptr<YieldTermStructure> (
			 new FlatForward(SettlementDate,
			 bond->yield(Clean_Price,
			 bondDayCountConvention,
			 Compounded,
			 bondCouponFrequency),
			 bondDayCountConvention,
			 Compounded,
			 bondCouponFrequency)));

			 */
		 //std::cout << bond->yield(Clean_Price,bondDayCountConvention,Simple,bondCouponFrequency,bondMaturityDate);
		 //std::cout << bond->yield(bondDayCountConvention,Simple,bondCouponFrequency);
		 
		
		  //std::cout <<  bond->cleanPrice();

		 
		 std::cout <<  bond->yield(Clean_Price,
						bondDayCountConvention,
						 Compounded,
						 bondCouponFrequency);
						 
		 std::cin.get();
		 return 0;
		 

		 //std::cout << 

    } catch (std::exception& e) {
        std::cerr << e.what() << std::endl;\
		std::cin.get();
        return 1;
    }
	    catch (...) 
		{
        std::cerr << "unknown error" << std::endl;
		std::cin.get();
        return 1;
    }
}