Logo Search packages:      
Sourcecode: quantlib version File versions  Download package

exchangerate.cpp

/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 Copyright (C) 2004 StatPro Italia srl

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 <quantlib-dev@lists.sf.net>. The license is also available online at
 <http://quantlib.org/reference/license.html>.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

#include "exchangerate.hpp"
#include <ql/exchangerate.hpp>
#include <ql/Currencies/all.hpp>

using namespace QuantLib;
using namespace boost::unit_test_framework;

void ExchangeRateTest::testDirect() {

    BOOST_MESSAGE("Testing direct exchange rates...");

    ExchangeRate eur_usd = ExchangeRate(EURCurrency(), USDCurrency(), 1.2042);

    Money m1(50000.0, EURCurrency());
    Money m2(100000.0, USDCurrency());

    Money::conversionType = Money::NoConversion;

    Money calculated = eur_usd.exchange(m1);
    Money expected(m1.value()*eur_usd.rate(), USDCurrency());

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    calculated = eur_usd.exchange(m2);
    expected = Money(m2.value()/eur_usd.rate(), EURCurrency());

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }
}

void ExchangeRateTest::testDerived() {

    BOOST_MESSAGE("Testing derived exchange rates...");

    ExchangeRate eur_usd = ExchangeRate(EURCurrency(), USDCurrency(), 1.2042);
    ExchangeRate eur_gbp = ExchangeRate(EURCurrency(), GBPCurrency(), 0.6612);

    ExchangeRate derived = ExchangeRate::chain(eur_usd, eur_gbp);

    Money m1(50000.0, GBPCurrency());
    Money m2(100000.0, USDCurrency());

    Money::conversionType = Money::NoConversion;

    Money calculated = derived.exchange(m1);
    Money expected(m1.value()*eur_usd.rate()/eur_gbp.rate(), USDCurrency());

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    calculated = derived.exchange(m2);
    expected = Money(m2.value()*eur_gbp.rate()/eur_usd.rate(), GBPCurrency());

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }
}

void ExchangeRateTest::testDirectLookup() {

    BOOST_MESSAGE("Testing lookup of direct exchange rates...");

    ExchangeRateManager& rateManager = ExchangeRateManager::instance();
    rateManager.clear();

    ExchangeRate eur_usd1 = ExchangeRate(EURCurrency(), USDCurrency(), 1.1983);
    ExchangeRate eur_usd2 = ExchangeRate(USDCurrency(), EURCurrency(),
                                         1.0/1.2042);
    rateManager.add(eur_usd1, Date(4,August,2004));
    rateManager.add(eur_usd2, Date(5,August,2004));

    Money m1(50000.0, EURCurrency());
    Money m2(100000.0, USDCurrency());

    Money::conversionType = Money::NoConversion;

    ExchangeRate eur_usd = rateManager.lookup(EURCurrency(),
                                              USDCurrency(),
                                              Date(4,August,2004),
                                              ExchangeRate::Direct);
    Money calculated = eur_usd.exchange(m1);
    Money expected(m1.value()*eur_usd1.rate(), USDCurrency());

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    eur_usd = rateManager.lookup(EURCurrency(),
                                 USDCurrency(),
                                 Date(5,August,2004),
                                 ExchangeRate::Direct);
    calculated = eur_usd.exchange(m1);
    expected = Money(m1.value()/eur_usd2.rate(), USDCurrency());

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    ExchangeRate usd_eur = rateManager.lookup(USDCurrency(),
                                              EURCurrency(),
                                              Date(4,August,2004),
                                              ExchangeRate::Direct);

    calculated = usd_eur.exchange(m2);
    expected = Money(m2.value()/eur_usd1.rate(), EURCurrency());

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    usd_eur = rateManager.lookup(USDCurrency(),
                                 EURCurrency(),
                                 Date(5,August,2004),
                                 ExchangeRate::Direct);

    calculated = usd_eur.exchange(m2);
    expected = Money(m2.value()*eur_usd2.rate(), EURCurrency());

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }
}

void ExchangeRateTest::testTriangulatedLookup() {

    BOOST_MESSAGE("Testing lookup of triangulated exchange rates...");

    ExchangeRateManager& rateManager = ExchangeRateManager::instance();
    rateManager.clear();

    ExchangeRate eur_usd1 = ExchangeRate(EURCurrency(), USDCurrency(), 1.1983);
    ExchangeRate eur_usd2 = ExchangeRate(EURCurrency(), USDCurrency(), 1.2042);
    rateManager.add(eur_usd1, Date(4,August,2004));
    rateManager.add(eur_usd2, Date(5,August,2004));

    Money m1(50000000.0, ITLCurrency());
    Money m2(100000.0, USDCurrency());

    Money::conversionType = Money::NoConversion;

    ExchangeRate itl_usd = rateManager.lookup(ITLCurrency(),
                                              USDCurrency(),
                                              Date(4,August,2004));
    Money calculated = itl_usd.exchange(m1);
    Money expected(m1.value()*eur_usd1.rate()/1936.27, USDCurrency());

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    itl_usd = rateManager.lookup(ITLCurrency(),
                                 USDCurrency(),
                                 Date(5,August,2004));
    calculated = itl_usd.exchange(m1);
    expected = Money(m1.value()*eur_usd2.rate()/1936.27, USDCurrency());

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    ExchangeRate usd_itl = rateManager.lookup(USDCurrency(),
                                              ITLCurrency(),
                                              Date(4,August,2004));

    calculated = usd_itl.exchange(m2);
    expected = Money(m2.value()*1936.27/eur_usd1.rate(), ITLCurrency());

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    usd_itl = rateManager.lookup(USDCurrency(),
                                 ITLCurrency(),
                                 Date(5,August,2004));

    calculated = usd_itl.exchange(m2);
    expected = Money(m2.value()*1936.27/eur_usd2.rate(), ITLCurrency());

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }
}

void ExchangeRateTest::testSmartLookup() {

    BOOST_MESSAGE("Testing lookup of derived exchange rates...");

    Currency EUR = EURCurrency(), USD = USDCurrency(), GBP = GBPCurrency(),
             CHF = CHFCurrency(), SEK = SEKCurrency(), JPY = JPYCurrency();

    ExchangeRateManager& rateManager = ExchangeRateManager::instance();
    rateManager.clear();

    ExchangeRate eur_usd1 = ExchangeRate(EUR, USD, 1.1983);
    ExchangeRate eur_usd2 = ExchangeRate(USD, EUR, 1.0/1.2042);
    rateManager.add(eur_usd1, Date(4,August,2004));
    rateManager.add(eur_usd2, Date(5,August,2004));

    ExchangeRate eur_gbp1 = ExchangeRate(GBP, EUR, 1.0/0.6596);
    ExchangeRate eur_gbp2 = ExchangeRate(EUR, GBP, 0.6612);
    rateManager.add(eur_gbp1, Date(4,August,2004));
    rateManager.add(eur_gbp2, Date(5,August,2004));

    ExchangeRate usd_chf1 = ExchangeRate(USD, CHF, 1.2847);
    ExchangeRate usd_chf2 = ExchangeRate(CHF, USD, 1.0/1.2774);
    rateManager.add(usd_chf1, Date(4,August,2004));
    rateManager.add(usd_chf2, Date(5,August,2004));

    ExchangeRate chf_sek1 = ExchangeRate(SEK, CHF, 0.1674);
    ExchangeRate chf_sek2 = ExchangeRate(CHF, SEK, 1.0/0.1677);
    rateManager.add(chf_sek1, Date(4,August,2004));
    rateManager.add(chf_sek2, Date(5,August,2004));

    ExchangeRate jpy_sek1 = ExchangeRate(SEK, JPY, 14.5450);
    ExchangeRate jpy_sek2 = ExchangeRate(JPY, SEK, 1.0/14.6110);
    rateManager.add(jpy_sek1, Date(4,August,2004));
    rateManager.add(jpy_sek2, Date(5,August,2004));

    Money m1(100000.0, USD);
    Money m2(100000.0, EUR);
    Money m3(100000.0, GBP);
    Money m4(100000.0, CHF);
    Money m5(100000.0, SEK);
    Money m6(100000.0, JPY);

    Money::conversionType = Money::NoConversion;

    // two-rate chain

    ExchangeRate usd_sek = rateManager.lookup(USD, SEK, Date(4,August,2004));
    Money calculated = usd_sek.exchange(m1);
    Money expected(m1.value()*usd_chf1.rate()/chf_sek1.rate(), SEK);

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    usd_sek = rateManager.lookup(SEK, USD, Date(5,August,2004));
    calculated = usd_sek.exchange(m5);
    expected = Money(m5.value()*usd_chf2.rate()/chf_sek2.rate(), USD);

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    // three-rate chain

    ExchangeRate eur_sek = rateManager.lookup(EUR, SEK, Date(4,August,2004));
    calculated = eur_sek.exchange(m2);
    expected = Money(m2.value()*eur_usd1.rate()
                               *usd_chf1.rate()/chf_sek1.rate(), SEK);

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    eur_sek = rateManager.lookup(SEK, EUR, Date(5,August,2004));
    calculated = eur_sek.exchange(m5);
    expected = Money(m5.value()*eur_usd2.rate()
                               *usd_chf2.rate()/chf_sek2.rate(), EUR);

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    // four-rate chain

    ExchangeRate eur_jpy = rateManager.lookup(EUR, JPY, Date(4,August,2004));
    calculated = eur_jpy.exchange(m2);
    expected = Money(m2.value()*eur_usd1.rate()*usd_chf1.rate()
                               *jpy_sek1.rate()/chf_sek1.rate(), JPY);

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    eur_jpy = rateManager.lookup(JPY, EUR, Date(5,August,2004));
    calculated = eur_jpy.exchange(m6);
    expected = Money(m6.value()*jpy_sek2.rate()*eur_usd2.rate()
                               *usd_chf2.rate()/chf_sek2.rate(), EUR);

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    // five-rate chain

    ExchangeRate gbp_jpy = rateManager.lookup(GBP, JPY, Date(4,August,2004));
    calculated = gbp_jpy.exchange(m3);
    expected = Money(m3.value()*eur_gbp1.rate()*eur_usd1.rate()*usd_chf1.rate()
                               *jpy_sek1.rate()/chf_sek1.rate(), JPY);

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }

    gbp_jpy = rateManager.lookup(JPY, GBP, Date(5,August,2004));
    calculated = gbp_jpy.exchange(m6);
    expected = Money(m6.value()*jpy_sek2.rate()*eur_usd2.rate()*usd_chf2.rate()
                               *eur_gbp2.rate()/chf_sek2.rate(), GBP);

    if (!close(calculated,expected)) {
        BOOST_FAIL("Wrong result: \n"
                   << "    expected:   " << expected << "\n"
                   << "    calculated: " << calculated);
    }
}

test_suite* ExchangeRateTest::suite() {
    test_suite* suite = BOOST_TEST_SUITE("Exchange-rate tests");
    suite->add(BOOST_TEST_CASE(&ExchangeRateTest::testDirect));
    suite->add(BOOST_TEST_CASE(&ExchangeRateTest::testDerived));
    suite->add(BOOST_TEST_CASE(&ExchangeRateTest::testDirectLookup));
    suite->add(BOOST_TEST_CASE(&ExchangeRateTest::testTriangulatedLookup));
    suite->add(BOOST_TEST_CASE(&ExchangeRateTest::testSmartLookup));
    return suite;
}


Generated by  Doxygen 1.6.0   Back to index