class Money::Bank::OANDA

Constants

INSTRUMENTS_URL
RATES_URL

Attributes

rates_expiration[R]

@return [Time] Returns the time when the rates expire.

ttl_in_seconds[R]

@return [Integer] Returns the Time To Live (TTL) in seconds.

Public Class Methods

new(account_id, access_token, opts={}) click to toggle source
# File lib/oanda_bank.rb, line 23
def initialize(account_id, access_token, opts={})
  @client = OAuth2::Client.new(nil, nil)
  @access_token = OAuth2::AccessToken.new(@client, access_token)
  @account_id = account_id
  @updating_mutex = Mutex.new
  setup
end

Public Instance Methods

expire_rates() click to toggle source
# File lib/oanda_bank.rb, line 66
def expire_rates
  if @ttl_in_seconds && @rates_expiration <= Time.now
    if @updating_mutex.try_lock
      begin
        update_rates!
        true
      ensure
        @updating_mutex.unlock
      end
    end
  else
    false
  end
end
get_rate(from, to, opts = {}) click to toggle source
# File lib/oanda_bank.rb, line 43
def get_rate(from, to, opts = {})
  expire_rates
  fn = Proc.new do
    straight_through = @rates[rate_key_for(from, to)]
    if straight_through
      straight_through
    else
      to_usd   = @rates[rate_key_for(from, 'USD')]
      from_usd = @rates[rate_key_for('USD', to)]
      if (to_usd && from_usd)
        to_usd * from_usd
      else
        nil
      end
    end
  end
  if opts[:without_mutex]
    fn.call
  else
    @mutex.synchronize { fn.call }
  end
end
ttl_in_seconds=(value) click to toggle source

Set the Time To Live (TTL) in seconds.

@param [Integer] the seconds between an expiration and another.

# File lib/oanda_bank.rb, line 85
def ttl_in_seconds=(value)
  @ttl_in_seconds = value
  refresh_rates_expiration! if ttl_in_seconds
end
update_rates!() click to toggle source
# File lib/oanda_bank.rb, line 31
def update_rates!
  begin
    new_rates = fetch_rates
    @mutex.synchronize do
      @rates = new_rates
      refresh_rates_expiration!
    end
  rescue StandardError => e
    raise FetchError.new(e.message)
  end
end

Protected Instance Methods

fetch_rates() click to toggle source
# File lib/oanda_bank.rb, line 92
def fetch_rates
  instruments = @access_token.get("#{INSTRUMENTS_URL}?accountId=#{@account_id}")
  instruments = JSON.parse(instruments.body)

  instrument_codes = instruments['instruments'].map do |instrument|
    instrument['instrument']
  end

  instruments_argument = instrument_codes.join('%2C')

  rates = @access_token.get("#{RATES_URL}?instruments=#{instruments_argument}")
  rates = JSON.parse(rates.body)
  rates = rates['prices']

  result = {}
  rates.each do |rate|
    match = /(?<base>[A-Z0-9]+)_(?<quote>[A-Z0-9]+)/.match(rate['instrument'])

    if !match
      next
    end

    from  = match[:base].upcase
    to    = match[:quote].upcase

    if !Money::Currency.find(from) || !Money::Currency.find(to)
      next
    end

    result[rate_key_for(from, to)] = rate['bid'].to_d
    result[rate_key_for(to, from)] = (1/rate['ask']).to_d
  end
  result
end

Private Instance Methods

refresh_rates_expiration!() click to toggle source
# File lib/oanda_bank.rb, line 129
def refresh_rates_expiration!
  if @ttl_in_seconds
    @rates_expiration = Time.now + @ttl_in_seconds
  end
end