82 lines
2.3 KiB
Ruby
82 lines
2.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "net/http"
|
|
require "ox"
|
|
|
|
require "provider/adapters/adapter"
|
|
|
|
class Provider
|
|
module Adapters
|
|
# Bank of Lithuania (Lietuvos Bankas). Publishes daily exchange rates for
|
|
# ~88 currencies. Pre-2015 rates are quoted against LTL (Lithuanian litas);
|
|
# post-2015 rates are EUR-based (ECB rates republished after euro adoption).
|
|
class LB < Adapter
|
|
BASE_URL = "https://www.lb.lt/webservices/FxRates/FxRates.asmx/getFxRates"
|
|
EUR_ADOPTION = Date.new(2015, 1, 1)
|
|
|
|
class << self
|
|
def backfill_range = 30
|
|
end
|
|
|
|
def fetch(after: nil, upto: nil)
|
|
end_date = upto || Date.today
|
|
dataset = []
|
|
|
|
first = true
|
|
(after..end_date).each do |date|
|
|
next if date.saturday? || date.sunday?
|
|
|
|
sleep(0.2) unless first
|
|
first = false
|
|
|
|
dataset.concat(fetch_date(date))
|
|
end
|
|
|
|
dataset
|
|
end
|
|
|
|
def parse(xml)
|
|
doc = Ox.load(xml)
|
|
|
|
doc.locate("*/FxRate").filter_map do |fx_rate|
|
|
amounts = fx_rate.locate("CcyAmt")
|
|
next unless amounts.size == 2
|
|
|
|
first_ccy = amounts[0].locate("Ccy/^String").first
|
|
first_amt = amounts[0].locate("Amt/^String").first
|
|
second_ccy = amounts[1].locate("Ccy/^String").first
|
|
second_amt = amounts[1].locate("Amt/^String").first
|
|
date_str = fx_rate.locate("Dt/^String").first
|
|
|
|
next unless first_ccy && first_amt && second_ccy && second_amt && date_str
|
|
|
|
date = Date.parse(date_str)
|
|
tp = fx_rate.locate("Tp/^String").first
|
|
|
|
if tp == "LT"
|
|
quote_amt = Float(first_amt)
|
|
base_quantity = Float(second_amt)
|
|
next if quote_amt.zero? || base_quantity.zero?
|
|
|
|
{ date:, base: second_ccy, quote: "LTL", rate: quote_amt / base_quantity }
|
|
else
|
|
rate = Float(second_amt)
|
|
next if rate.zero?
|
|
|
|
{ date:, base: "EUR", quote: second_ccy, rate: }
|
|
end
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def fetch_date(date)
|
|
tp = date < EUR_ADOPTION ? "LT" : "EU"
|
|
url = URI(BASE_URL)
|
|
url.query = URI.encode_www_form(tp:, dt: date.strftime("%Y-%m-%d"))
|
|
response = Net::HTTP.get(url)
|
|
parse(response)
|
|
end
|
|
end
|
|
end
|
|
end
|