Class: ExchangeRates

Inherits:
Object
  • Object
show all
Defined in:
lib/exchange_rates.rb,
lib/exchange_rates/version.rb

Overview

Exchange Rates is responsible for parsing a locally available XML file listing ratios between the base_currency and target currencies. All currencies should be provided as strings with their 3 letter code.

Constant Summary collapse

VERSION =
"0.2.1"

Class Method Summary collapse

Class Method Details

.at(date, from, to) ⇒ Object

ExchangeRates.at gives an exchange rate between two currencies at a particular date. Raises exceptions if the dates are out of range of the file or if the currencies are unknown.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/exchange_rates.rb', line 11

def self.at(date, from, to)
  parse_rates
  if rates = @@rates[date]
    unless from_rate = rates[from]
      if from == @@base_currency
        from_rate = 1.0
      else
        raise "Unknown 'from' currency"
      end
    end
    unless to_rate = rates[to]
      if to == @@base_currency
        to_rate = 1.0
      else
        raise "Unknown 'to' currency"
      end
    end
    to_rate / from_rate
  else
    raise "Date out of known dates."
  end  
end

.available_currenciesObject

Outputs an array of supported currencies.



95
96
97
98
# File 'lib/exchange_rates.rb', line 95

def self.available_currencies
  parse_rates
  @@rates.first[1].keys + [@@base_currency]
end

.available_datesObject

Outputs an array of dates included in the current data set.



89
90
91
92
# File 'lib/exchange_rates.rb', line 89

def self.available_dates
  parse_rates
  @@rates.keys
end

.convert(amount, opts = {}) ⇒ Object

Converts an amount of money between currencies. The options for this method are:

from - from currency, defaults to base_currency (typically EUR)
to   - to currency, defaults to  base_currency (typically EUR)
date - date at which to perform conversion, defaults to current date


39
40
41
42
43
# File 'lib/exchange_rates.rb', line 39

def self.convert(amount, opts = {})
  parse_rates
  options = {from: @@base_currency, to: @@base_currency, date: Date.today}.merge(opts)
  amount.to_f * at(options[:date], options[:from], options[:to])
end

.over_time(from, to) ⇒ Object

Calculates exchange rates between two currencies over all available dates.



46
47
48
49
50
51
52
53
# File 'lib/exchange_rates.rb', line 46

def self.over_time(from, to)
  parse_rates
  results = {}
  @@rates.each do |date, rates|
    results[date] = self.at(date, from, to)
  end
  results
end

.parse_ratesObject

Reads and parses the XML data feed providing the underlying data source. The data source is currently assumed to be in the format of the European Central Bank feed accesible at <www.ecb.europa.eu/stats/eurofxref/eurofxref­hist­90d.xml> which provides a 90 day history of exchange rates. It is assumed that this file is saved locally, best through a cron tab (see README). If a different source is to be used, call the ‘set_rates` method.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/exchange_rates.rb', line 61

def self.parse_rates
  @@rates ||= nil
  return @@rates if @@rates
  @@base_currency = 'EUR'
  rate_file = ENV['EXCHANGE_RATE_FILE'] || './exchange-rates.xml'
  doc = Nokogiri::XML(File.read(rate_file))
  @@rates = {}
  doc.css('Cube>Cube[time]').each do |day|
    time = Date.parse day.attr('time')
    @@rates[time] = {}
    day.css('Cube').each{ |c| 
      @@rates[time][c.attr('currency')] = c.attr('rate').to_f
    }
  end
  @@rates
end

.set_rates(rates, base = 'EUR') ⇒ Object

Set custom rates data. The data should be a hash of hashes, where the keys in the outer hash are Date objects and the keys in the inner hashes are three letter currency codes. The values are floats showing the exchange rate between a currency and the base currency. This second argument should be the base currency to which all values are relative to.



83
84
85
86
# File 'lib/exchange_rates.rb', line 83

def self.set_rates(rates, base = 'EUR')
  @@rates = rates
  @@base_currency = base
end