20#include <boost/make_shared.hpp>
21#include <boost/test/unit_test.hpp>
22#include <ql/currencies/all.hpp>
23#include <ql/indexes/indexmanager.hpp>
24#include <ql/quotes/simplequote.hpp>
25#include <ql/termstructures/yield/flatforward.hpp>
26#include <ql/time/calendars/target.hpp>
27#include <ql/time/daycounters/actualactual.hpp>
34using namespace boost::unit_test_framework;
39BOOST_AUTO_TEST_SUITE(CashFlowTest)
43 BOOST_TEST_MESSAGE(
"Testing FX Linked CashFlow");
46 Settings::instance().evaluationDate() = Date(5, Jan, 2016);
47 Date today = Settings::instance().evaluationDate();
49 Date cfDate1(5, Jan, 2015);
50 Date cfDate2(5, Jan, 2016);
51 Date cfDate3(5, Jan, 2017);
53 Real foreignAmount = 1000000;
54 QuantLib::ext::shared_ptr<SimpleQuote> sq = QuantLib::ext::make_shared<SimpleQuote>(123.45);
55 Handle<Quote> spot(sq);
56 DayCounter dc = ActualActual(ActualActual::ISDA);
57 Calendar cal = TARGET();
58 Handle<YieldTermStructure> domYTS(QuantLib::ext::shared_ptr<YieldTermStructure>(
new FlatForward(0, cal, 0.005, dc)));
59 Handle<YieldTermStructure> forYTS(QuantLib::ext::shared_ptr<YieldTermStructure>(
new FlatForward(0, cal, 0.03, dc)));
61 QuantLib::ext::shared_ptr<FxIndex> fxIndex =
62 QuantLib::ext::make_shared<FxIndex>(
"FX::USDJPY", 0, USDCurrency(), JPYCurrency(), TARGET(), spot, domYTS, forYTS);
69 fxIndex->addFixing(cfDate1, 112.0);
70 fxIndex->addFixing(cfDate2, sq->value());
72 BOOST_TEST_MESSAGE(
"Check historical flow is correct");
73 BOOST_CHECK_CLOSE(fxlcf1.
amount(), 112000000.0, 1e-10);
75 BOOST_TEST_MESSAGE(
"Check todays flow is correct");
76 BOOST_CHECK_CLOSE(fxlcf2.
amount(), 123450000.0, 1e-10);
78 BOOST_TEST_MESSAGE(
"Check future (expected) flow is correct");
79 Real fwd = sq->value() * domYTS->discount(cfDate3) / forYTS->discount(cfDate3);
80 BOOST_CHECK_CLOSE(fxlcf3.
amount(), foreignAmount * fwd, 1e-10);
83 Settings::instance().evaluationDate() = Date(1, Feb, 2016);
87 BOOST_CHECK_CLOSE(fxlcf1.
amount(), 112000000.0, 1e-10);
90 fwd = sq->value() * domYTS->discount(cfDate3) / forYTS->discount(cfDate3);
91 BOOST_CHECK_CLOSE(fxlcf3.
amount(), foreignAmount * fwd, 1e-10);
94 Settings::instance().evaluationDate() = today;
99 BOOST_TEST_MESSAGE(
"Testing Equity Coupon");
102 Settings::instance().evaluationDate() = Date(5, Jan, 2016);
103 Date today = Settings::instance().evaluationDate();
105 Date cfDate1(4, Dec, 2015);
106 Date cfDate2(5, Apr, 2016);
107 Date fixingDate1(31, Dec, 2015);
108 Date fixingDate2(1, Apr, 2016);
110 Real nominal = 1000000;
111 string eqName =
"SP5";
112 QuantLib::ext::shared_ptr<SimpleQuote> sq = QuantLib::ext::make_shared<SimpleQuote>(2100);
113 Handle<Quote> spot(sq);
114 DayCounter dc = ActualActual(ActualActual::ISDA);
115 Calendar cal = TARGET();
116 Currency ccy = USDCurrency();
117 Natural fixingLag = 2;
118 Real divFactor = 1.0;
119 Handle<YieldTermStructure> dividend(
120 QuantLib::ext::shared_ptr<YieldTermStructure>(
new FlatForward(0, cal, 0.01, dc)));
121 Handle<YieldTermStructure> equityforecast(
122 QuantLib::ext::shared_ptr<YieldTermStructure>(
new FlatForward(0, cal, 0.02, dc)));
124 QuantLib::ext::shared_ptr<EquityIndex2> eqIndex =
125 QuantLib::ext::make_shared<EquityIndex2>(eqName, cal, ccy, spot, equityforecast, dividend);
127 eqIndex->addFixing(cfDate1, 2000);
128 eqIndex->addFixing(fixingDate1, 1980);
131 EquityCoupon eq1(cfDate2, nominal, today, cfDate2, 0, eqIndex, dc, EquityReturnType::Price);
133 EquityCoupon eq2(cfDate2, nominal, today, cfDate2, 0, eqIndex, dc, EquityReturnType::Total, divFactor);
135 EquityCoupon eq3(cfDate2, nominal, cfDate1, cfDate2, 0, eqIndex, dc, EquityReturnType::Price);
137 EquityCoupon eq4(cfDate2, nominal, today, cfDate2, fixingLag, eqIndex, dc, EquityReturnType::Total);
140 Handle<YieldTermStructure> domYTS(QuantLib::ext::shared_ptr<YieldTermStructure>(
new FlatForward(0, cal, 0.01, dc)));
141 Handle<YieldTermStructure> forYTS(QuantLib::ext::shared_ptr<YieldTermStructure>(
new FlatForward(0, cal, 0.02, dc)));
142 Handle<Quote> fxSpot(QuantLib::ext::make_shared<SimpleQuote>(1.1));
143 QuantLib::ext::shared_ptr<FxIndex> fxIndex =
144 QuantLib::ext::make_shared<FxIndex>(
"FX::EURUSD", 2, EURCurrency(), USDCurrency(), TARGET(), fxSpot, domYTS, forYTS);
146 fxIndex->addFixing(cfDate1, 1.09);
149 EquityCoupon eq5(cfDate2, nominal, today, cfDate2, 0, eqIndex, dc, EquityReturnType::Total, 1.0,
false,
150 Null<Real>(), Null<Real>(), Date(), Date(), Date(), Date(), Date(), fxIndex);
164 Time dt = dc.yearFraction(today, cfDate2);
165 Real forward = spot->value() * std::exp((0.02 - 0.01) * dt);
166 Real expectedAmount = nominal * (forward - spot->value()) / spot->value();
167 BOOST_TEST_MESSAGE(
"Check Price Return is correct.");
168 BOOST_CHECK_CLOSE(eq1.
amount(), expectedAmount, 1e-10);
171 forward = spot->value() * std::exp((0.02 - 0.01) * dt);
172 Real div = spot->value() * std::exp((0.02) * dt) - forward;
173 expectedAmount = nominal * (forward + divFactor * div - spot->value()) / spot->value();
174 BOOST_TEST_MESSAGE(
"Check Total Return is correct");
175 BOOST_CHECK_CLOSE(eq2.
amount(), expectedAmount, 1e-10);
178 forward = spot->value() * std::exp((0.02 - 0.01) * dt);
179 expectedAmount = nominal * (forward - eqIndex->fixing(cfDate1)) / eqIndex->fixing(cfDate1);
180 BOOST_TEST_MESSAGE(
"Check Historical starting Price Return is correct.");
181 BOOST_CHECK_CLOSE(eq3.
amount(), expectedAmount, 1e-10);
184 dt = dc.yearFraction(today, fixingDate2);
185 forward = spot->value() * std::exp(0.02 * dt);
186 expectedAmount = nominal * (forward - eqIndex->fixing(fixingDate1)) / eqIndex->fixing(fixingDate1);
187 BOOST_TEST_MESSAGE(
"Check Total Return fixing lag handling is correct.");
188 BOOST_CHECK_CLOSE(eq4.
amount(), expectedAmount, 1e-10);
191 dt = dc.yearFraction(today, cfDate2);
192 forward = spot->value() * std::exp((0.02 - 0.01) * dt);
193 div = spot->value() * std::exp((0.02) * dt) - forward;
195 nominal * ((forward + div) * fxIndex->fixing(cfDate2) - spot->value() * 1.1) / (spot->value() * 1.1);
196 BOOST_TEST_MESSAGE(
"Check Total Return with underlying in different ccy handling is correct.");
197 BOOST_CHECK_CLOSE(eq5.
amount(), expectedAmount, 1e-10);
200BOOST_AUTO_TEST_SUITE_END()
202BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(testFXLinkedCashFlow)
void setPricer(const QuantLib::ext::shared_ptr< EquityCouponPricer > &)
Real amount() const override
Pricer for equity coupons.
Real amount() const override
coupon paying the return on an equity
Pricer for equity coupons.
Fixture that can be used at top level.