Пример #1
0
        public void testDirect()
        {
            Currency EUR = new EURCurrency(), USD = new USDCurrency();

             ExchangeRate eur_usd = new ExchangeRate(EUR, USD, 1.2042);

             Money m1 = 50000.0 * EUR;
             Money m2 = 100000.0 * USD;

             Money.conversionType = Money.ConversionType.NoConversion;

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

             if (!Utils.close(calculated, expected))
             {
               Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

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

             if (!Utils.close(calculated, expected))
             {
               Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }
        }
Пример #2
0
        public void testBaseCurrency()
        {
            Currency EUR = new EURCurrency(), GBP = new GBPCurrency(), USD = new USDCurrency();

             Money m1 = 50000.0 * GBP;
             Money m2 = 100000.0 * EUR;
             Money m3 = 500000.0 * USD;

             ExchangeRateManager.Instance.clear();
             ExchangeRate eur_usd = new ExchangeRate(EUR, USD, 1.2042);
             ExchangeRate eur_gbp = new ExchangeRate(EUR, GBP, 0.6612);
             ExchangeRateManager.Instance.add(eur_usd);
             ExchangeRateManager.Instance.add(eur_gbp);

             Money.conversionType = Money.ConversionType.BaseCurrencyConversion;
             Money.baseCurrency = EUR;

             Money calculated = m1 * 3.0 + 2.5 * m2 - m3 / 5.0;

             Rounding round = Money.baseCurrency.rounding;
             double x = round.Round(m1.value * 3.0 / eur_gbp.rate) + 2.5 * m2.value
                 - round.Round(m3.value / (5.0 * eur_usd.rate));
             Money expected = new Money(x, EUR);

             Money.conversionType = Money.ConversionType.NoConversion;

             if (calculated != expected)
             {
            Assert.Fail("Wrong result: expected: " + expected + "calculated: " + calculated);
             }
        }
Пример #3
0
        public void testDerived()
        {
            Currency EUR = new EURCurrency(), USD = new USDCurrency(), GBP = new GBPCurrency();

             ExchangeRate eur_usd = new ExchangeRate(EUR, USD, 1.2042);
             ExchangeRate eur_gbp = new ExchangeRate(EUR, GBP, 0.6612);

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

             Money m1 = 50000.0 * GBP;
             Money m2 = 100000.0 * USD;

             Money.conversionType = Money.ConversionType.NoConversion;

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }
        }
Пример #4
0
        /// <summary>
        /// Add an exchange rate.
        /// </summary>
        /// <param name="rate"></param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <remarks>
        /// The given rate is valid between the given dates.
        /// If two rates are given between the same currencies
        /// and with overlapping date ranges, the latest one
        /// added takes precedence during lookup.
        /// </remarks>
        private void add(ExchangeRate rate, Date startDate, Date endDate)
        {
            int k = hash(rate.source, rate.target);

            if (data_.ContainsKey(k))
            {
                data_[k].Insert(0, new Entry(rate, startDate, endDate));
            }
            else
            {
                data_[k] = new List <Entry>();
                data_[k].Add(new Entry(rate, startDate, endDate));
            }
        }
        private ExchangeRate smartLookup(Currency source, Currency target, Date date, List <int> forbidden)
        {
            // direct exchange rates are preferred.
            ExchangeRate direct = fetch(source, target, date);

            if (direct.HasValue)
            {
                return(direct);
            }

            // if none is found, turn to smart lookup. The source currency
            // is forbidden to subsequent lookups in order to avoid cycles.
            forbidden.Add(source.numericCode);

            foreach (KeyValuePair <int, List <Entry> > i in data_)
            {
                // we look for exchange-rate data which involve our source
                // currency...
                if (hashes(i.Key, source) && (i.Value.Count != 0))
                {
                    // ...whose other currency is not forbidden...
                    Entry    e     = i.Value[0];// front();
                    Currency other = source == e.rate.source ? e.rate.target : e.rate.source;
                    if (!forbidden.Contains(other.numericCode))
                    {
                        // ...and which carries information for the requested date.
                        ExchangeRate head = fetch(source, other, date);
                        if (((Nullable <double>)head.rate).HasValue)
                        {
                            // if we can get to the target from here...
                            try
                            {
                                ExchangeRate tail = smartLookup(other, target, date, forbidden);
                                // ..we're done.
                                return(ExchangeRate.chain(head, tail));
                            }
                            catch (Exception)
                            {
                                // otherwise, we just discard this rate.
                                ;
                            }
                        }
                    }
                }
            }
            // if the loop completed, we have no way to return the requested rate.
            throw new Exception("no conversion available from " + source.code + " to " + target.code + " for " + date);
        }
        /// <summary>
        /// Lookup the exchange rate between two currencies at a given
        /// date.  If the given type is Direct, only direct exchange
        /// rates will be returned if available; if Derived, direct
        /// rates are still preferred but derived rates are allowed.
        /// </summary>
        /// <remarks>
        /// if two or more exchange-rate chains are possible
        /// which allow to specify a requested rate, it is
        /// unspecified which one is returned.
        /// </remarks>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <param name="date"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public ExchangeRate lookup(Currency source, Currency target, Date date, ExchangeRate.Type type)
        {
            if (source == target)
            {
                return(new ExchangeRate(source, target, 1.0));
            }

            if (date == new Date())
            {
                date = Settings.evaluationDate();
            }

            if (type == ExchangeRate.Type.Direct)
            {
                return(directLookup(source, target, date));
            }
            else if (!source.triangulationCurrency.empty())
            {
                Currency link = source.triangulationCurrency;
                if (link == target)
                {
                    return(directLookup(source, link, date));
                }
                else
                {
                    return(ExchangeRate.chain(directLookup(source, link, date), lookup(link, target, date)));
                }
            }
            else if (!target.triangulationCurrency.empty())
            {
                Currency link = target.triangulationCurrency;
                if (source == link)
                {
                    return(directLookup(link, target, date));
                }
                else
                {
                    return(ExchangeRate.chain(lookup(source, link, date), directLookup(link, target, date)));
                }
            }
            else
            {
                return(smartLookup(source, target, date));
            }
        }
Пример #7
0
        /// <summary>
        /// chain two exchange rates
        /// </summary>
        /// <param name="r1"></param>
        /// <param name="r2"></param>
        /// <returns></returns>
        public static ExchangeRate chain(ExchangeRate r1, ExchangeRate r2)
        {
            ExchangeRate result = new ExchangeRate();

            result.type_      = Type.Derived;
            result.rateChain_ = new KeyValuePair <ExchangeRate, ExchangeRate>(r1, r2);
            if (r1.source_ == r2.source_)
            {
                result.source_ = r1.target_;
                result.target_ = r2.target_;
                result.rate_   = r2.rate_ / r1.rate_;
            }
            else if (r1.source_ == r2.target_)
            {
                result.source_ = r1.target_;
                result.target_ = r2.source_;
                result.rate_   = 1.0 / (r1.rate_ * r2.rate_);
            }
            else if (r1.target_ == r2.source_)
            {
                result.source_ = r1.source_;
                result.target_ = r2.target_;
                result.rate_   = r1.rate_ * r2.rate_;
            }
            else if (r1.target_ == r2.target_)
            {
                result.source_ = r1.source_;
                result.target_ = r2.source_;
                result.rate_   = r1.rate_ / r2.rate_;
            }
            else
            {
                Utils.QL_FAIL("exchange rates not chainable");
            }
            return(result);
        }
Пример #8
0
        public void testTriangulatedLookup()
        {
            ExchangeRateManager rateManager = ExchangeRateManager.Instance;
             rateManager.clear();

             Currency EUR = new EURCurrency(), USD = new USDCurrency(), ITL = new ITLCurrency();

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

             Money m1 = 50000000.0 * ITL;
             Money m2 = 100000.0 * USD;

             Money.conversionType = Money.ConversionType.NoConversion;

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

             ExchangeRate usd_itl = rateManager.lookup(USD, ITL, new Date(4, Month.August, 2004));

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

             usd_itl = rateManager.lookup(USD, ITL, new Date(5, Month.August, 2004));

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }
        }
Пример #9
0
        public void testSmartLookup()
        {
            Currency EUR = new EURCurrency(), USD = new USDCurrency(), GBP = new GBPCurrency(),
                  CHF = new CHFCurrency(), SEK = new SEKCurrency(), JPY = new JPYCurrency();

             ExchangeRateManager rateManager = ExchangeRateManager.Instance;
             rateManager.clear();

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

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

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

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

             ExchangeRate jpy_sek1 = new ExchangeRate(SEK, JPY, 14.5450);
             ExchangeRate jpy_sek2 = new ExchangeRate(JPY, SEK, 1.0 / 14.6110);
             rateManager.add(jpy_sek1, new Date(4,Month.August,2004));
             rateManager.add(jpy_sek2, new Date(5,Month.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.ConversionType.NoConversion;

             // two-rate chain

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

             // three-rate chain

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

             // four-rate chain

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

             // five-rate chain

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }
        }
Пример #10
0
      /// <summary>
      /// Lookup the exchange rate between two currencies at a given
      /// date.  If the given type is Direct, only direct exchange
      /// rates will be returned if available; if Derived, direct
      /// rates are still preferred but derived rates are allowed.
      /// </summary>
      /// <remarks>
      /// if two or more exchange-rate chains are possible
      /// which allow to specify a requested rate, it is
      /// unspecified which one is returned.
      /// </remarks>
      /// <param name="source"></param>
      /// <param name="target"></param>
      /// <param name="date"></param>
      /// <param name="type"></param>
      /// <returns></returns>
      public ExchangeRate lookup(Currency source, Currency target, Date date, ExchangeRate.Type type)
      {

         if (source == target)
            return new ExchangeRate(source, target, 1.0);

         if (date == new Date())
            date = Settings.evaluationDate();

         if (type == ExchangeRate.Type.Direct)
         {
            return directLookup(source, target, date);
         }
         else if (!source.triangulationCurrency.empty())
         {
            Currency link = source.triangulationCurrency;
            if (link == target)
               return directLookup(source, link, date);
            else
               return ExchangeRate.chain(directLookup(source, link, date), lookup(link, target, date));
         }
         else if (!target.triangulationCurrency.empty())
         {
            Currency link = target.triangulationCurrency;
            if (source == link)
               return directLookup(link, target, date);
            else
               return ExchangeRate.chain(lookup(source, link, date), directLookup(link, target, date));
         }
         else
         {
            return smartLookup(source, target, date);
         }

      }
 public void add(ExchangeRate rate)
 {
     add(rate, Date.minDate(), Date.maxDate());
 }
Пример #12
0
 public void add(ExchangeRate rate, Date startDate)
 {
     add(rate, startDate, Date.maxDate());
 }
Пример #13
0
 public void add(ExchangeRate rate)
 {
     add(rate, Date.minDate(), Date.maxDate());
 }
Пример #14
0
 public Entry(ExchangeRate r, Date s, Date e)
 {
    rate = r;
    startDate = s;
    endDate = e;
 }
Пример #15
0
 /// <summary>
 /// chain two exchange rates
 /// </summary>
 /// <param name="r1"></param>
 /// <param name="r2"></param>
 /// <returns></returns>
 public static ExchangeRate chain(ExchangeRate r1, ExchangeRate r2)
 {
     ExchangeRate result = new ExchangeRate();
     result.type_ = Type.Derived;
     result.rateChain_ = new KeyValuePair<ExchangeRate,ExchangeRate>(r1,r2);
     if (r1.source_ == r2.source_)
     {
        result.source_ = r1.target_;
        result.target_ = r2.target_;
        result.rate_ = r2.rate_ / r1.rate_;
     }
     else if (r1.source_ == r2.target_)
     {
        result.source_ = r1.target_;
        result.target_ = r2.source_;
        result.rate_ = 1.0 / (r1.rate_ * r2.rate_);
     }
     else if (r1.target_ == r2.source_)
     {
        result.source_ = r1.source_;
        result.target_ = r2.target_;
        result.rate_ = r1.rate_ * r2.rate_;
     }
     else if (r1.target_ == r2.target_)
     {
        result.source_ = r1.source_;
        result.target_ = r2.source_;
        result.rate_ = r1.rate_ / r2.rate_;
     }
     else
     {
         throw new Exception ("exchange rates not chainable");
     }
     return result;
 }
 public Entry(ExchangeRate r, Date s, Date e)
 {
     rate      = r;
     startDate = s;
     endDate   = e;
 }
Пример #17
0
        public void testDirectLookup()
        {
            ExchangeRateManager rateManager = ExchangeRateManager.Instance;
             rateManager.clear();

             Currency EUR = new EURCurrency(), USD = new USDCurrency();

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

             Money m1 = 50000.0 * EUR;
             Money m2 = 100000.0 * USD;

             Money.conversionType = Money.ConversionType.NoConversion;

             ExchangeRate eur_usd = rateManager.lookup(EUR, USD,new Date(4,Month.August,2004),ExchangeRate.Type.Direct);
             Money calculated = eur_usd.exchange(m1);
             Money expected = new Money(m1.value*eur_usd1.rate, USD);

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

             eur_usd = rateManager.lookup(EUR, USD,new Date(5,Month.August,2004),ExchangeRate.Type.Direct);
             calculated = eur_usd.exchange(m1);
             expected = new Money(m1.value/eur_usd2.rate, USD);

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

             ExchangeRate usd_eur = rateManager.lookup(USD, EUR,new Date(4,Month.August,2004),ExchangeRate.Type.Direct);

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }

             usd_eur = rateManager.lookup(USD, EUR,new Date(5,Month.August,2004),ExchangeRate.Type.Direct);

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

             if (!Utils.close(calculated, expected))
             {
            Assert.Fail("Wrong result: expected: " + expected + " calculated: " + calculated);
             }
        }
 public void add(ExchangeRate rate, Date startDate)
 {
     add(rate, startDate, Date.maxDate());
 }
Пример #19
0
 /// <summary>
 /// Add an exchange rate.
 /// </summary>
 /// <param name="rate"></param>
 /// <param name="startDate"></param>
 /// <param name="endDate"></param>
 /// <remarks>
 /// The given rate is valid between the given dates.
 /// If two rates are given between the same currencies
 /// and with overlapping date ranges, the latest one
 /// added takes precedence during lookup.
 /// </remarks> 
 private void add(ExchangeRate rate, Date startDate, Date endDate)
 {
    int k = hash(rate.source, rate.target);
    if (data_.ContainsKey(k))
    {
       data_[k].Insert(0,new Entry(rate, startDate, endDate));
    }
    else
    {
       data_[k] = new List<Entry>() ;
       data_[k].Add(new Entry(rate, startDate, endDate));
    }
 }