currency 0.4.6 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Manifest.txt +2 -0
 - data/Releases.txt +16 -0
 - data/TODO.txt +2 -0
 - data/lib/currency/currency_version.rb +1 -1
 - data/lib/currency/exchange.rb +2 -0
 - data/lib/currency/exchange/rate.rb +13 -2
 - data/lib/currency/exchange/rate/source/federal_reserve.rb +160 -0
 - data/lib/currency/exchange/rate/source/historical/rate.rb +20 -18
 - data/lib/currency/exchange/rate/source/new_york_fed.rb +16 -0
 - data/lib/currency/exchange/rate/source/provider.rb +8 -6
 - data/test/federal_reserve_test.rb +75 -0
 - metadata +4 -2
 
    
        data/Manifest.txt
    CHANGED
    
    | 
         @@ -22,6 +22,7 @@ lib/currency/exchange/rate/deriver.rb 
     | 
|
| 
       22 
22 
     | 
    
         
             
            lib/currency/exchange/rate/source.rb
         
     | 
| 
       23 
23 
     | 
    
         
             
            lib/currency/exchange/rate/source/base.rb
         
     | 
| 
       24 
24 
     | 
    
         
             
            lib/currency/exchange/rate/source/failover.rb
         
     | 
| 
      
 25 
     | 
    
         
            +
            lib/currency/exchange/rate/source/federal_reserve.rb
         
     | 
| 
       25 
26 
     | 
    
         
             
            lib/currency/exchange/rate/source/historical.rb
         
     | 
| 
       26 
27 
     | 
    
         
             
            lib/currency/exchange/rate/source/historical/rate.rb
         
     | 
| 
       27 
28 
     | 
    
         
             
            lib/currency/exchange/rate/source/historical/writer.rb
         
     | 
| 
         @@ -42,6 +43,7 @@ test/ar_simple_test.rb 
     | 
|
| 
       42 
43 
     | 
    
         
             
            test/ar_test_base.rb
         
     | 
| 
       43 
44 
     | 
    
         
             
            test/ar_test_core.rb
         
     | 
| 
       44 
45 
     | 
    
         
             
            test/config_test.rb
         
     | 
| 
      
 46 
     | 
    
         
            +
            test/federal_reserve_test.rb
         
     | 
| 
       45 
47 
     | 
    
         
             
            test/formatter_test.rb
         
     | 
| 
       46 
48 
     | 
    
         
             
            test/historical_writer_test.rb
         
     | 
| 
       47 
49 
     | 
    
         
             
            test/macro_test.rb
         
     | 
    
        data/Releases.txt
    CHANGED
    
    | 
         @@ -1,5 +1,21 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            = Currency Release History
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            == Release 0.4.7: 2007/06/25
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            CRITICAL FIXES
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            * NewYorkFed: CRITICAL FIX:
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              Rates for USDAUD, USDEUR, USDNZD and USDGBP were reciprocals.
         
     | 
| 
      
 10 
     | 
    
         
            +
              See http://www.newyorkfed.org/markets/fxrates/noon.cfm
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            * FederalReserve: Added support for historical rates from http://www.federalreserve.gov/releases/H10/hist
         
     | 
| 
      
 13 
     | 
    
         
            +
            * Provider#get_rate(): Return first rate immediately.
         
     | 
| 
      
 14 
     | 
    
         
            +
            * Rate::Writable for rate summary computation support.
         
     | 
| 
      
 15 
     | 
    
         
            +
            * Rate: collect_rate(): fixed rate_date_1.
         
     | 
| 
      
 16 
     | 
    
         
            +
            * Historical::Rate: to_rate(): takes optional class.
         
     | 
| 
      
 17 
     | 
    
         
            +
            * Historical::Rate: from_rate(): fixed rate_samples.
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
       3 
19 
     | 
    
         
             
            == Release 0.4.6: 2007/05/29
         
     | 
| 
       4 
20 
     | 
    
         | 
| 
       5 
21 
     | 
    
         
             
            * NewYorkFed: changed FEXtime to FEXTIME.
         
     | 
    
        data/TODO.txt
    CHANGED
    
    
    
        data/lib/currency/exchange.rb
    CHANGED
    
    
| 
         @@ -1,6 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Copyright (C) 2006-2007 Kurt Stephens <ruby-currency(at)umleta.com>
         
     | 
| 
       2 
2 
     | 
    
         
             
            # See LICENSE.txt for details.
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
      
 4 
     | 
    
         
            +
            require 'currency/exchange'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
       4 
6 
     | 
    
         
             
            # Represents a convertion rate between two currencies at a given period of time.
         
     | 
| 
       5 
7 
     | 
    
         
             
            class Currency::Exchange::Rate
         
     | 
| 
       6 
8 
     | 
    
         
             
                # The first Currency.
         
     | 
| 
         @@ -132,7 +134,6 @@ class Currency::Exchange::Rate 
     | 
|
| 
       132 
134 
     | 
    
         
             
                  @source ||= rate.source
         
     | 
| 
       133 
135 
     | 
    
         
             
                  @c1 ||= rate.c1
         
     | 
| 
       134 
136 
     | 
    
         
             
                  @c2 ||= rate.c2
         
     | 
| 
       135 
     | 
    
         
            -
                  @date ||= rate.date
         
     | 
| 
       136 
137 
     | 
    
         | 
| 
       137 
138 
     | 
    
         
             
                  # Reciprocal?
         
     | 
| 
       138 
139 
     | 
    
         
             
                  if @c1 == rate.c2 && @c2 == rate.c1
         
     | 
| 
         @@ -170,7 +171,7 @@ class Currency::Exchange::Rate 
     | 
|
| 
       170 
171 
     | 
    
         
             
                    d = rate.date_1 || rate.date
         
     | 
| 
       171 
172 
     | 
    
         
             
                    unless @date_1 && @date_1 > d
         
     | 
| 
       172 
173 
     | 
    
         
             
                      @date_1 = d 
         
     | 
| 
       173 
     | 
    
         
            -
                      @ 
     | 
| 
      
 174 
     | 
    
         
            +
                      @rate_date_1 = r
         
     | 
| 
       174 
175 
     | 
    
         
             
                    end
         
     | 
| 
       175 
176 
     | 
    
         | 
| 
       176 
177 
     | 
    
         
             
                    @date ||= rate.date || rate.date0 || rate.date1
         
     | 
| 
         @@ -190,3 +191,13 @@ class Currency::Exchange::Rate 
     | 
|
| 
       190 
191 
     | 
    
         
             
            end # class
         
     | 
| 
       191 
192 
     | 
    
         | 
| 
       192 
193 
     | 
    
         | 
| 
      
 194 
     | 
    
         
            +
            class Currency::Exchange::Rate::Writable < Currency::Exchange::Rate
         
     | 
| 
      
 195 
     | 
    
         
            +
              attr_writer :source
         
     | 
| 
      
 196 
     | 
    
         
            +
              attr_writer :derived
         
     | 
| 
      
 197 
     | 
    
         
            +
              attr_writer :rate
         
     | 
| 
      
 198 
     | 
    
         
            +
              def initialize(c1 = nil, c2 = nil, rate = nil, *opts)
         
     | 
| 
      
 199 
     | 
    
         
            +
                super(c1, c2, 0.0, *opts)
         
     | 
| 
      
 200 
     | 
    
         
            +
                @rate = rate
         
     | 
| 
      
 201 
     | 
    
         
            +
              end
         
     | 
| 
      
 202 
     | 
    
         
            +
            end # class
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,160 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Copyright (C) 2006-2007 Kurt Stephens <ruby-currency(at)umleta.com>
         
     | 
| 
      
 2 
     | 
    
         
            +
            # See LICENSE.txt for details.
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require 'currency/exchange/rate/source/provider'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            require 'net/http'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'open-uri'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            # Connects to http://www.federalreserve.gov/releases/H10/hist/dat00_<country>.txtb
         
     | 
| 
      
 11 
     | 
    
         
            +
            # Parses all known currency files.
         
     | 
| 
      
 12 
     | 
    
         
            +
            # 
         
     | 
| 
      
 13 
     | 
    
         
            +
            class Currency::Exchange::Rate::Source::FederalReserve < ::Currency::Exchange::Rate::Source::Provider
         
     | 
| 
      
 14 
     | 
    
         
            +
              # Defines the pivot currency for http://www.federalreserve.gov/releases/H10/hist/dat00_#{country_code}.txt data files.
         
     | 
| 
      
 15 
     | 
    
         
            +
              PIVOT_CURRENCY = :USD
         
     | 
| 
      
 16 
     | 
    
         
            +
              
         
     | 
| 
      
 17 
     | 
    
         
            +
              # Arbitrary currency code used by www.federalreserve.gov for
         
     | 
| 
      
 18 
     | 
    
         
            +
              # naming historical data files.
         
     | 
| 
      
 19 
     | 
    
         
            +
              # Used internally.
         
     | 
| 
      
 20 
     | 
    
         
            +
              attr_accessor :country_code
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              def initialize(*opt)
         
     | 
| 
      
 23 
     | 
    
         
            +
                self.uri = 'http://www.federalreserve.gov/releases/H10/hist/dat00_#{country_code}.txt'
         
     | 
| 
      
 24 
     | 
    
         
            +
                self.country_code = '' 
         
     | 
| 
      
 25 
     | 
    
         
            +
                @raw_rates = nil
         
     | 
| 
      
 26 
     | 
    
         
            +
                super(*opt)
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
              
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              # Returns 'federalreserve.gov'.
         
     | 
| 
      
 31 
     | 
    
         
            +
              def name
         
     | 
| 
      
 32 
     | 
    
         
            +
                'federalreserve.gov'
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              # FIXME?
         
     | 
| 
      
 37 
     | 
    
         
            +
              #def available?(time = nil)
         
     | 
| 
      
 38 
     | 
    
         
            +
              #  time ||= Time.now
         
     | 
| 
      
 39 
     | 
    
         
            +
              #  ! [0, 6].include?(time.wday) ? true : false
         
     | 
| 
      
 40 
     | 
    
         
            +
              #end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              def clear_rates
         
     | 
| 
      
 44 
     | 
    
         
            +
                @raw_rates = nil
         
     | 
| 
      
 45 
     | 
    
         
            +
                super
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
              
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              def raw_rates
         
     | 
| 
      
 50 
     | 
    
         
            +
                rates
         
     | 
| 
      
 51 
     | 
    
         
            +
                @raw_rates
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
              # Maps bizzare federalreserve.gov country codes to ISO currency codes.
         
     | 
| 
      
 55 
     | 
    
         
            +
              # May only work for the dat00_XX.txt data files.
         
     | 
| 
      
 56 
     | 
    
         
            +
              # See http://www.jhall.demon.co.uk/currency/by_country.html
         
     | 
| 
      
 57 
     | 
    
         
            +
              #
         
     | 
| 
      
 58 
     | 
    
         
            +
              # Some data files list reciprocal rates!
         
     | 
| 
      
 59 
     | 
    
         
            +
              @@country_to_currency = 
         
     | 
| 
      
 60 
     | 
    
         
            +
                {
         
     | 
| 
      
 61 
     | 
    
         
            +
                'al' => [ :AUD, :USD ],
         
     | 
| 
      
 62 
     | 
    
         
            +
                # 'au' => :ASH, # AUSTRIAN SHILLING: pre-EUR?
         
     | 
| 
      
 63 
     | 
    
         
            +
                'bz' => [ :USD, :BRL ],
         
     | 
| 
      
 64 
     | 
    
         
            +
                'ca' => [ :USD, :CAD ],
         
     | 
| 
      
 65 
     | 
    
         
            +
                'ch' => [ :USD, :CNY ],
         
     | 
| 
      
 66 
     | 
    
         
            +
                'dn' => [ :USD, :DKK ],
         
     | 
| 
      
 67 
     | 
    
         
            +
                'eu' => [ :EUR, :USD ],
         
     | 
| 
      
 68 
     | 
    
         
            +
                # 'gr' => :XXX, # Greece Drachma: pre-EUR?
         
     | 
| 
      
 69 
     | 
    
         
            +
                'hk' => [ :USD, :HKD ],
         
     | 
| 
      
 70 
     | 
    
         
            +
                'in' => [ :USD, :INR ],
         
     | 
| 
      
 71 
     | 
    
         
            +
                'ja' => [ :USD, :JPY ],
         
     | 
| 
      
 72 
     | 
    
         
            +
                'ma' => [ :USD, :MYR ],
         
     | 
| 
      
 73 
     | 
    
         
            +
                'mx' => [ :USD, :MXN ], # OR MXP?
         
     | 
| 
      
 74 
     | 
    
         
            +
                'nz' => [ :NZD, :USD ],
         
     | 
| 
      
 75 
     | 
    
         
            +
                'no' => [ :USD, :NOK ],
         
     | 
| 
      
 76 
     | 
    
         
            +
                'ko' => [ :USD, :KRW ],
         
     | 
| 
      
 77 
     | 
    
         
            +
                'sf' => [ :USD, :ZAR ],
         
     | 
| 
      
 78 
     | 
    
         
            +
                'sl' => [ :USD, :LKR ],
         
     | 
| 
      
 79 
     | 
    
         
            +
                'sd' => [ :USD, :SEK ],
         
     | 
| 
      
 80 
     | 
    
         
            +
                'sz' => [ :USD, :CHF ],
         
     | 
| 
      
 81 
     | 
    
         
            +
                'ta' => [ :USD, :TWD ], # New Taiwan Dollar.
         
     | 
| 
      
 82 
     | 
    
         
            +
                'th' => [ :USD, :THB ],
         
     | 
| 
      
 83 
     | 
    
         
            +
                'uk' => [ :GBP, :USD ],
         
     | 
| 
      
 84 
     | 
    
         
            +
                've' => [ :USD, :VEB ],
         
     | 
| 
      
 85 
     | 
    
         
            +
              }
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
              # Parses text file for rates.
         
     | 
| 
      
 89 
     | 
    
         
            +
              def parse_rates(data = nil)
         
     | 
| 
      
 90 
     | 
    
         
            +
                data = get_page_content unless data
         
     | 
| 
      
 91 
     | 
    
         
            +
                
         
     | 
| 
      
 92 
     | 
    
         
            +
                rates = [ ]
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                @raw_rates ||= { }
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                $stderr.puts "#{self}: parse_rates: data =\n#{data}" if @verbose
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                # Rates are USD/currency so
         
     | 
| 
      
 99 
     | 
    
         
            +
                # c1 = currency
         
     | 
| 
      
 100 
     | 
    
         
            +
                # c2 = :USD
         
     | 
| 
      
 101 
     | 
    
         
            +
                c1, c2 = @@country_to_currency[country_code]
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                unless c1 && c2
         
     | 
| 
      
 104 
     | 
    
         
            +
                  raise(::Currency::Exception::UnavailableRates, "Cannot determine currency code for federalreserve.gov country code #{country_code.inspect}")
         
     | 
| 
      
 105 
     | 
    
         
            +
                end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                data.split(/\r?\n\r?/).each do | line |
         
     | 
| 
      
 108 
     | 
    
         
            +
                  #        day     month             yy       rate
         
     | 
| 
      
 109 
     | 
    
         
            +
                  m = /^\s*(\d\d?)-([A-Z][a-z][a-z])-(\d\d)\s+([\d\.]+)/.match(line)
         
     | 
| 
      
 110 
     | 
    
         
            +
                  next unless m
         
     | 
| 
      
 111 
     | 
    
         
            +
                  
         
     | 
| 
      
 112 
     | 
    
         
            +
                  day = m[1].to_i
         
     | 
| 
      
 113 
     | 
    
         
            +
                  month = m[2]
         
     | 
| 
      
 114 
     | 
    
         
            +
                  year = m[3].to_i
         
     | 
| 
      
 115 
     | 
    
         
            +
                  if year >= 50 and year < 100
         
     | 
| 
      
 116 
     | 
    
         
            +
                    year += 1900
         
     | 
| 
      
 117 
     | 
    
         
            +
                  elsif year < 50
         
     | 
| 
      
 118 
     | 
    
         
            +
                    year += 2000
         
     | 
| 
      
 119 
     | 
    
         
            +
                  end
         
     | 
| 
      
 120 
     | 
    
         
            +
                  
         
     | 
| 
      
 121 
     | 
    
         
            +
                  date = Time.parse("#{day}-#{month}-#{year} 12:00:00 -05:00") # USA NY => EST
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                  rate = m[4].to_f
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                  STDERR.puts "#{c1} #{c2} #{rate} #{date}" if @verbose
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                  rates << new_rate(c1, c2, rate, date)
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                  ((@raw_rates[date] ||= { })[c1] ||= { })[c2] ||= rate
         
     | 
| 
      
 130 
     | 
    
         
            +
                  ((@raw_rates[date] ||= { })[c2] ||= { })[c1] ||= 1.0 / rate
         
     | 
| 
      
 131 
     | 
    
         
            +
                end
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                # Put most recent rate first.
         
     | 
| 
      
 134 
     | 
    
         
            +
                # See Provider#get_rate.
         
     | 
| 
      
 135 
     | 
    
         
            +
                rates.reverse!
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
                # $stderr.puts "rates = #{rates.inspect}"
         
     | 
| 
      
 138 
     | 
    
         
            +
                raise ::Currency::Exception::UnavailableRates, "No rates found in #{get_uri.inspect}" if rates.empty?
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                rates
         
     | 
| 
      
 141 
     | 
    
         
            +
              end
         
     | 
| 
      
 142 
     | 
    
         
            +
              
         
     | 
| 
      
 143 
     | 
    
         
            +
              
         
     | 
| 
      
 144 
     | 
    
         
            +
              # Return a list of known base rates.
         
     | 
| 
      
 145 
     | 
    
         
            +
              def load_rates(time = nil)
         
     | 
| 
      
 146 
     | 
    
         
            +
                # $stderr.puts "#{self}: load_rates(#{time})" if @verbose
         
     | 
| 
      
 147 
     | 
    
         
            +
                self.date = time
         
     | 
| 
      
 148 
     | 
    
         
            +
                rates = [ ]
         
     | 
| 
      
 149 
     | 
    
         
            +
                @@country_to_currency.keys.each do | cc |
         
     | 
| 
      
 150 
     | 
    
         
            +
                  self.country_code = cc
         
     | 
| 
      
 151 
     | 
    
         
            +
                  rates.push(*parse_rates)
         
     | 
| 
      
 152 
     | 
    
         
            +
                end
         
     | 
| 
      
 153 
     | 
    
         
            +
                rates
         
     | 
| 
      
 154 
     | 
    
         
            +
              end
         
     | 
| 
      
 155 
     | 
    
         
            +
              
         
     | 
| 
      
 156 
     | 
    
         
            +
             
         
     | 
| 
      
 157 
     | 
    
         
            +
            end # class
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
         @@ -56,6 +56,7 @@ class Currency::Exchange::Rate::Source::Historical::Rate < ::ActiveRecord::Base 
     | 
|
| 
       56 
56 
     | 
    
         
             
                 self.c2 = rate.c2.code.to_s
         
     | 
| 
       57 
57 
     | 
    
         
             
                 self.rate = rate.rate
         
     | 
| 
       58 
58 
     | 
    
         
             
                 self.rate_avg = rate.rate_avg
         
     | 
| 
      
 59 
     | 
    
         
            +
                 self.rate_samples = rate.rate_samples
         
     | 
| 
       59 
60 
     | 
    
         
             
                 self.rate_lo  = rate.rate_lo
         
     | 
| 
       60 
61 
     | 
    
         
             
                 self.rate_hi  = rate.rate_hi
         
     | 
| 
       61 
62 
     | 
    
         
             
                 self.rate_date_0  = rate.rate_date_0
         
     | 
| 
         @@ -78,24 +79,25 @@ class Currency::Exchange::Rate::Source::Historical::Rate < ::ActiveRecord::Base 
     | 
|
| 
       78 
79 
     | 
    
         | 
| 
       79 
80 
     | 
    
         | 
| 
       80 
81 
     | 
    
         
             
               # Creates a new Currency::Exchange::Rate object.
         
     | 
| 
       81 
     | 
    
         
            -
               def to_rate
         
     | 
| 
       82 
     | 
    
         
            -
                  
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
      
 82 
     | 
    
         
            +
               def to_rate(cls = ::Currency::Exchange::Rate)
         
     | 
| 
      
 83 
     | 
    
         
            +
                 cls.
         
     | 
| 
      
 84 
     | 
    
         
            +
                   new(
         
     | 
| 
      
 85 
     | 
    
         
            +
                       ::Currency::Currency.get(self.c1), 
         
     | 
| 
      
 86 
     | 
    
         
            +
                       ::Currency::Currency.get(self.c2),
         
     | 
| 
      
 87 
     | 
    
         
            +
                       self.rate,
         
     | 
| 
      
 88 
     | 
    
         
            +
                       "historical #{self.source}",
         
     | 
| 
      
 89 
     | 
    
         
            +
                       self.date,
         
     | 
| 
      
 90 
     | 
    
         
            +
                       self.derived,
         
     | 
| 
      
 91 
     | 
    
         
            +
                       {
         
     | 
| 
      
 92 
     | 
    
         
            +
                         :rate_avg => self.rate_avg,
         
     | 
| 
      
 93 
     | 
    
         
            +
                         :rate_samples => self.rate_samples,
         
     | 
| 
      
 94 
     | 
    
         
            +
                         :rate_lo => self.rate_lo,
         
     | 
| 
      
 95 
     | 
    
         
            +
                         :rate_hi => self.rate_hi,
         
     | 
| 
      
 96 
     | 
    
         
            +
                         :rate_date_0 => self.rate_date_0,
         
     | 
| 
      
 97 
     | 
    
         
            +
                         :rate_date_1 => self.rate_date_1,
         
     | 
| 
      
 98 
     | 
    
         
            +
                         :date_0 => self.date_0,
         
     | 
| 
      
 99 
     | 
    
         
            +
                         :date_1 => self.date_1
         
     | 
| 
      
 100 
     | 
    
         
            +
                       })
         
     | 
| 
       99 
101 
     | 
    
         
             
               end
         
     | 
| 
       100 
102 
     | 
    
         | 
| 
       101 
103 
     | 
    
         | 
| 
         @@ -47,6 +47,17 @@ class Currency::Exchange::Rate::Source::NewYorkFed < ::Currency::Exchange::Rate: 
     | 
|
| 
       47 
47 
     | 
    
         
             
                rates
         
     | 
| 
       48 
48 
     | 
    
         
             
                @raw_rates
         
     | 
| 
       49 
49 
     | 
    
         
             
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
              
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              # The fed swaps rates on some currency pairs!
         
     | 
| 
      
 53 
     | 
    
         
            +
              # See http://www.newyorkfed.org/markets/fxrates/noon.cfm (LISTS AUD!)
         
     | 
| 
      
 54 
     | 
    
         
            +
              # http://www.newyorkfed.org/xml/fx.html (DOES NOT LIST AUD!)
         
     | 
| 
      
 55 
     | 
    
         
            +
              @@swap_units = {
         
     | 
| 
      
 56 
     | 
    
         
            +
                :AUD => true,
         
     | 
| 
      
 57 
     | 
    
         
            +
                :EUR => true,
         
     | 
| 
      
 58 
     | 
    
         
            +
                :NZD => true,
         
     | 
| 
      
 59 
     | 
    
         
            +
                :GBP => true,
         
     | 
| 
      
 60 
     | 
    
         
            +
              }
         
     | 
| 
       50 
61 
     | 
    
         | 
| 
       51 
62 
     | 
    
         | 
| 
       52 
63 
     | 
    
         
             
              # Parses XML for rates.
         
     | 
| 
         @@ -80,6 +91,11 @@ class Currency::Exchange::Rate::Source::NewYorkFed < ::Currency::Exchange::Rate: 
     | 
|
| 
       80 
91 
     | 
    
         
             
                  date = date.text
         
     | 
| 
       81 
92 
     | 
    
         
             
                  date = Time.parse("#{date} 12:00:00 -05:00") # USA NY => EST
         
     | 
| 
       82 
93 
     | 
    
         | 
| 
      
 94 
     | 
    
         
            +
                  # Handle arbitrary rate reciprocals!
         
     | 
| 
      
 95 
     | 
    
         
            +
                  if @@swap_units[c1] || @@swap_units[c2]
         
     | 
| 
      
 96 
     | 
    
         
            +
                    c1, c2 = c2, c1
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
       83 
99 
     | 
    
         
             
                  rates << new_rate(c1, c2, rate, date)
         
     | 
| 
       84 
100 
     | 
    
         | 
| 
       85 
101 
     | 
    
         
             
                  (@raw_rates[c1] ||= { })[c2] ||= rate
         
     | 
| 
         @@ -94,14 +94,16 @@ class Currency::Exchange::Rate::Source::Provider < Currency::Exchange::Rate::Sou 
     | 
|
| 
       94 
94 
     | 
    
         
             
              end
         
     | 
| 
       95 
95 
     | 
    
         | 
| 
       96 
96 
     | 
    
         | 
| 
       97 
     | 
    
         
            -
              # Return a matching base rate 
     | 
| 
      
 97 
     | 
    
         
            +
              # Return a matching base rate.
         
     | 
| 
       98 
98 
     | 
    
         
             
              def get_rate(c1, c2, time)
         
     | 
| 
       99 
     | 
    
         
            -
                 
     | 
| 
       100 
     | 
    
         
            -
                  rate 
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
      
 99 
     | 
    
         
            +
                rates.each do | rate |
         
     | 
| 
      
 100 
     | 
    
         
            +
                  return rate if 
         
     | 
| 
      
 101 
     | 
    
         
            +
                    rate.c1 == c1 &&
         
     | 
| 
      
 102 
     | 
    
         
            +
                    rate.c2 == c2 &&
         
     | 
| 
      
 103 
     | 
    
         
            +
                    (! time || normalize_time(rate.date) == time)
         
     | 
| 
       103 
104 
     | 
    
         
             
                end
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                nil
         
     | 
| 
       105 
107 
     | 
    
         
             
              end
         
     | 
| 
       106 
108 
     | 
    
         | 
| 
       107 
109 
     | 
    
         
             
              alias :get_rate_base :get_rate
         
     | 
| 
         @@ -0,0 +1,75 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Copyright (C) 2006-2007 Kurt Stephens <ruby-currency(at)umleta.com>
         
     | 
| 
      
 2 
     | 
    
         
            +
            # See LICENSE.txt for details.
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require 'test/test_base'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            require 'currency' # For :type => :money
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'currency/exchange/rate/source/federal_reserve'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            module Currency
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            class FederalReserveTest < TestBase
         
     | 
| 
      
 12 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 13 
     | 
    
         
            +
                super
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              @@available = nil
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              # New York Fed rates are not available on Saturday and Sunday.
         
     | 
| 
      
 20 
     | 
    
         
            +
              def available?
         
     | 
| 
      
 21 
     | 
    
         
            +
                if @@available == nil
         
     | 
| 
      
 22 
     | 
    
         
            +
                  @@available = @source.available?
         
     | 
| 
      
 23 
     | 
    
         
            +
                  STDERR.puts "Warning: FederalReserve unavailable on Saturday and Sunday, skipping tests." unless @@available
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
                @@available
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              def get_rate_source
         
     | 
| 
      
 30 
     | 
    
         
            +
                # Force FederalReserve Exchange.
         
     | 
| 
      
 31 
     | 
    
         
            +
                verbose = false
         
     | 
| 
      
 32 
     | 
    
         
            +
                source = @source = Exchange::Rate::Source::FederalReserve.new(:verbose => verbose)
         
     | 
| 
      
 33 
     | 
    
         
            +
                deriver = Exchange::Rate::Deriver.new(:source => source, :verbose => source.verbose)
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
              def test_usd_cad
         
     | 
| 
      
 39 
     | 
    
         
            +
                return unless available?
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                # yesterday = Time.now.to_date - 1
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                assert_not_nil rates = Exchange::Rate::Source.default.source.raw_rates
         
     | 
| 
      
 44 
     | 
    
         
            +
                #assert_not_nil rates[:USD]
         
     | 
| 
      
 45 
     | 
    
         
            +
                #assert_not_nil usd_cad = rates[:USD][:CAD]
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                assert_not_nil usd = Money.new(123.45, :USD)
         
     | 
| 
      
 48 
     | 
    
         
            +
                assert_not_nil cad = usd.convert(:CAD)
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                # assert_kind_of Numeric, m = (cad.to_f / usd.to_f)
         
     | 
| 
      
 51 
     | 
    
         
            +
                # $stderr.puts "m = #{m}"
         
     | 
| 
      
 52 
     | 
    
         
            +
                # assert_equal_float usd_cad, m, 0.001
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              def test_cad_eur
         
     | 
| 
      
 57 
     | 
    
         
            +
                return unless available?
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                assert_not_nil rates = Exchange::Rate::Source.default.source.raw_rates
         
     | 
| 
      
 60 
     | 
    
         
            +
                #assert_not_nil rates[:USD]
         
     | 
| 
      
 61 
     | 
    
         
            +
                #assert_not_nil usd_cad = rates[:USD][:CAD]
         
     | 
| 
      
 62 
     | 
    
         
            +
                #assert_not_nil usd_eur = rates[:USD][:EUR]
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                assert_not_nil cad = Money.new(123.45, :CAD)
         
     | 
| 
      
 65 
     | 
    
         
            +
                assert_not_nil eur = cad.convert(:EUR)
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                #assert_kind_of Numeric, m = (eur.to_f / cad.to_f)
         
     | 
| 
      
 68 
     | 
    
         
            +
                # $stderr.puts "m = #{m}"
         
     | 
| 
      
 69 
     | 
    
         
            +
                #assert_equal_float (1.0 / usd_cad) * usd_eur, m, 0.001
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            end # module
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -3,8 +3,8 @@ rubygems_version: 0.9.0 
     | 
|
| 
       3 
3 
     | 
    
         
             
            specification_version: 1
         
     | 
| 
       4 
4 
     | 
    
         
             
            name: currency
         
     | 
| 
       5 
5 
     | 
    
         
             
            version: !ruby/object:Gem::Version 
         
     | 
| 
       6 
     | 
    
         
            -
              version: 0.4. 
     | 
| 
       7 
     | 
    
         
            -
            date: 2007- 
     | 
| 
      
 6 
     | 
    
         
            +
              version: 0.4.7
         
     | 
| 
      
 7 
     | 
    
         
            +
            date: 2007-06-25 00:00:00 -04:00
         
     | 
| 
       8 
8 
     | 
    
         
             
            summary: "Currency models currencies, monetary values, foreign exchanges rates.   Pulls live and historical rates from http://xe.com/, http://newyorkfed.org/, http://thefinancials.com/. Can store/retrieve historical rate data from database using ActiveRecord. Can store/retrieve Money values using ActiveRecord.  For more details, see:  http://rubyforge.org/projects/currency/ http://currency.rubyforge.org/ http://currency.rubyforge.org/files/README_txt.html"
         
     | 
| 
       9 
9 
     | 
    
         
             
            require_paths: 
         
     | 
| 
       10 
10 
     | 
    
         
             
            - lib
         
     | 
| 
         @@ -54,6 +54,7 @@ files: 
     | 
|
| 
       54 
54 
     | 
    
         
             
            - lib/currency/exchange/rate/source.rb
         
     | 
| 
       55 
55 
     | 
    
         
             
            - lib/currency/exchange/rate/source/base.rb
         
     | 
| 
       56 
56 
     | 
    
         
             
            - lib/currency/exchange/rate/source/failover.rb
         
     | 
| 
      
 57 
     | 
    
         
            +
            - lib/currency/exchange/rate/source/federal_reserve.rb
         
     | 
| 
       57 
58 
     | 
    
         
             
            - lib/currency/exchange/rate/source/historical.rb
         
     | 
| 
       58 
59 
     | 
    
         
             
            - lib/currency/exchange/rate/source/historical/rate.rb
         
     | 
| 
       59 
60 
     | 
    
         
             
            - lib/currency/exchange/rate/source/historical/writer.rb
         
     | 
| 
         @@ -74,6 +75,7 @@ files: 
     | 
|
| 
       74 
75 
     | 
    
         
             
            - test/ar_test_base.rb
         
     | 
| 
       75 
76 
     | 
    
         
             
            - test/ar_test_core.rb
         
     | 
| 
       76 
77 
     | 
    
         
             
            - test/config_test.rb
         
     | 
| 
      
 78 
     | 
    
         
            +
            - test/federal_reserve_test.rb
         
     | 
| 
       77 
79 
     | 
    
         
             
            - test/formatter_test.rb
         
     | 
| 
       78 
80 
     | 
    
         
             
            - test/historical_writer_test.rb
         
     | 
| 
       79 
81 
     | 
    
         
             
            - test/macro_test.rb
         
     |