Class: Currency::Exchange::Rate::Source::FederalReserve

Inherits:
Provider show all
Defined in:
lib/currency/exchange/rate/source/federal_reserve.rb

Overview

Connects to www.federalreserve.gov/releases/H10/hist/dat00_<country>.txtb Parses all known currency files.

Constant Summary collapse

PIVOT_CURRENCY =

Defines the pivot currency for www.federalreserve.gov/releases/H10/hist/dat00_##country_code.txt data files.

:USD
@@country_to_currency =

Maps bizzare federalreserve.gov country codes to ISO currency codes. May only work for the dat00_XX.txt data files. See www.jhall.demon.co.uk/currency/by_country.html

Some data files list reciprocal rates!

{
  'al' => [ :AUD, :USD ],
  # 'au' => :ASH, # AUSTRIAN SHILLING: pre-EUR?
  'bz' => [ :USD, :BRL ],
  'ca' => [ :USD, :CAD ],
  'ch' => [ :USD, :CNY ],
  'dn' => [ :USD, :DKK ],
  'eu' => [ :EUR, :USD ],
  # 'gr' => :XXX, # Greece Drachma: pre-EUR?
  'hk' => [ :USD, :HKD ],
  'in' => [ :USD, :INR ],
  'ja' => [ :USD, :JPY ],
  'ma' => [ :USD, :MYR ],
  'mx' => [ :USD, :MXN ], # OR MXP?
  'nz' => [ :NZD, :USD ],
  'no' => [ :USD, :NOK ],
  'ko' => [ :USD, :KRW ],
  'sf' => [ :USD, :ZAR ],
  'sl' => [ :USD, :LKR ],
  'sd' => [ :USD, :SEK ],
  'sz' => [ :USD, :CHF ],
  'ta' => [ :USD, :TWD ], # New Taiwan Dollar.
  'th' => [ :USD, :THB ],
  'uk' => [ :GBP, :USD ],
  've' => [ :USD, :VEB ],
}

Instance Attribute Summary collapse

Attributes inherited from Provider

#date, #uri, #uri_path

Attributes inherited from Base

#pivot_currency, #time_quantitizer, #verbose

Instance Method Summary collapse

Methods inherited from Provider

#available?, #date_DD, #date_MM, #date_YYYY, #get_page_content, #get_rate, #get_uri, #rates

Methods inherited from Base

#__subclass_responsibility, #clear_rate, #convert, #currencies, #get_rate, #get_rate_base, #get_rates, #new_rate, #normalize_time, #rate, #rates, #to_s

Constructor Details

#initialize(*opt) ⇒ FederalReserve

Returns a new instance of FederalReserve.



22
23
24
25
26
27
# File 'lib/currency/exchange/rate/source/federal_reserve.rb', line 22

def initialize(*opt)
  self.uri = 'http://www.federalreserve.gov/releases/H10/hist/dat00_#{country_code}.txt'
  self.country_code = '' 
  @raw_rates = nil
  super(*opt)
end

Instance Attribute Details

#country_codeObject

Arbitrary currency code used by www.federalreserve.gov for naming historical data files. Used internally.



20
21
22
# File 'lib/currency/exchange/rate/source/federal_reserve.rb', line 20

def country_code
  @country_code
end

Instance Method Details

#clear_ratesObject



43
44
45
46
# File 'lib/currency/exchange/rate/source/federal_reserve.rb', line 43

def clear_rates
  @raw_rates = nil
  super
end

#load_rates(time = nil) ⇒ Object

Return a list of known base rates.



145
146
147
148
149
150
151
152
153
154
# File 'lib/currency/exchange/rate/source/federal_reserve.rb', line 145

def load_rates(time = nil)
  # $stderr.puts "#{self}: load_rates(#{time})" if @verbose
  self.date = time
  rates = [ ]
  @@country_to_currency.keys.each do | cc |
    self.country_code = cc
    rates.push(*parse_rates)
  end
  rates
end

#nameObject

Returns ‘federalreserve.gov’.



31
32
33
# File 'lib/currency/exchange/rate/source/federal_reserve.rb', line 31

def name
  'federalreserve.gov'
end

#parse_rates(data = nil) ⇒ Object

Parses text file for rates.



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/currency/exchange/rate/source/federal_reserve.rb', line 89

def parse_rates(data = nil)
  data = get_page_content unless data
  
  rates = [ ]

  @raw_rates ||= { }

  $stderr.puts "#{self}: parse_rates: data =\n#{data}" if @verbose

  # Rates are USD/currency so
  # c1 = currency
  # c2 = :USD
  c1, c2 = @@country_to_currency[country_code]

  unless c1 && c2
    raise ::Currency::Exception::UnavailableRates, "Cannot determine currency code for federalreserve.gov country code #{country_code.inspect}"
  end

  data.split(/\r?\n\r?/).each do | line |
    #        day     month             yy       rate
    m = /^\s*(\d\d?)-([A-Z][a-z][a-z])-(\d\d)\s+([\d\.]+)/.match(line)
    next unless m
    
    day = m[1].to_i
    month = m[2]
    year = m[3].to_i
    if year >= 50 and year < 100
      year += 1900
    elsif year < 50
      year += 2000
    end
    
    date = Time.parse("#{day}-#{month}-#{year} 12:00:00 -05:00") # USA NY => EST

    rate = m[4].to_f

    STDERR.puts "#{c1} #{c2} #{rate}\t#{date}" if @verbose

    rates << new_rate(c1, c2, rate, date)

    ((@raw_rates[date] ||= { })[c1] ||= { })[c2] ||= rate
    ((@raw_rates[date] ||= { })[c2] ||= { })[c1] ||= 1.0 / rate
  end

  # Put most recent rate first.
  # See Provider#get_rate.
  rates.reverse!

  # $stderr.puts "rates = #{rates.inspect}"
  raise ::Currency::Exception::UnavailableRates, "No rates found in #{get_uri.inspect}" if rates.empty?

  rates
end

#raw_ratesObject



49
50
51
52
# File 'lib/currency/exchange/rate/source/federal_reserve.rb', line 49

def raw_rates
  rates
  @raw_rates
end