frankfurter/lib/blender.rb

34 lines
749 B
Ruby
Raw Normal View History

2026-05-21 01:38:14 -06:00
# frozen_string_literal: true
require "base_conversion"
require "consensus"
require "weighted_average"
# Blends exchange rates from multiple providers into a single set. Rebases each provider to a common base,
# filters outliers via cross-provider consensus, then computes a recency-weighted average.
class Blender
attr_reader :rates, :base
def initialize(rates, base:)
@rates = rates.map { |r| r.is_a?(Hash) ? r : r.to_hash }
@base = base
end
def blend
WeightedAverage.new(consensus.annotated).calculate
end
def outliers
consensus.outliers
end
private
def consensus
@consensus ||= begin
rebased_rates = BaseConversion.new(rates, base:).convert
Consensus.new(rebased_rates)
end
end
end