Пример #1
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 ExchangeRateManagerEntry(rate, startDate, endDate));
            }
            else
            {
                _data[k] = new List <ExchangeRateManagerEntry> {
                    new ExchangeRateManagerEntry(rate, startDate, endDate)
                };
            }
        }
Пример #2
0
        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 <ExchangeRateManagerEntry> > 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...
                    ExchangeRateManagerEntry e = i.Value[0];                    // front();
                    Currency other             = source == e.Item1.source ? e.Item1.target : e.Item1.source;
                    if (!forbidden.Contains(other.numericCode))
                    {
                        // ...and which carries information for the requested date.
                        ExchangeRate head = Fetch(source, other, date);
                        if (((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)
                            {
                            }
                        }
                    }
                }
            }

            // 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);
        }
Пример #3
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);
        }
Пример #4
0
 public void Add(ExchangeRate rate, Date startDate)
 {
     Add(rate, startDate, Date.maxDate());
 }
Пример #5
0
 public void Add(ExchangeRate rate)
 {
     Add(rate, Date.minDate(), Date.maxDate());
 }
Пример #6
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;
        }