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.



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

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.



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

def country_code
  @country_code
end

Instance Method Details

#clear_ratesObject



40
41
42
43
# File 'lib/currency/exchange/rate/source/federal_reserve.rb', line 40

def clear_rates
  @raw_rates = nil
  super
end

#load_rates(time = nil) ⇒ Object

Return a list of known base rates.



138
139
140
141
142
143
144
145
146
147
# File 'lib/currency/exchange/rate/source/federal_reserve.rb', line 138

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’.



29
30
31
# File 'lib/currency/exchange/rate/source/federal_reserve.rb', line 29

def name
  'federalreserve.gov'
end

#parse_rates(data = nil) ⇒ Object

Parses text file for rates.



83
84
85
86
87
88
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
# File 'lib/currency/exchange/rate/source/federal_reserve.rb', line 83

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



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

def raw_rates
  rates
  @raw_rates
end