2024-10-04 14:19:45 -04:00
|
|
|
class Gapfiller
|
|
|
|
attr_reader :series
|
|
|
|
|
|
|
|
def initialize(series, start_date:, end_date:, cache:)
|
|
|
|
@series = series
|
|
|
|
@date_range = start_date..end_date
|
|
|
|
@cache = cache
|
|
|
|
end
|
|
|
|
|
|
|
|
def run
|
|
|
|
gapfilled_records = []
|
|
|
|
|
|
|
|
date_range.each do |date|
|
|
|
|
record = series.find { |r| r.date == date }
|
|
|
|
|
|
|
|
if should_gapfill?(date, record)
|
|
|
|
prev_record = gapfilled_records.find { |r| r.date == date - 1.day }
|
|
|
|
|
|
|
|
if prev_record
|
|
|
|
new_record = create_gapfilled_record(prev_record, date)
|
|
|
|
gapfilled_records << new_record
|
|
|
|
end
|
|
|
|
else
|
|
|
|
gapfilled_records << record if record
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
gapfilled_records
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
attr_reader :date_range, :cache
|
|
|
|
|
|
|
|
def should_gapfill?(date, record)
|
2024-10-10 18:02:12 -04:00
|
|
|
(date.on_weekend? || holiday?(date)) && record.nil?
|
|
|
|
end
|
|
|
|
|
|
|
|
def holiday?(date)
|
2024-10-10 19:29:20 -04:00
|
|
|
Holidays.on(date, :federalreserve, :us, :observed, :informal).any?
|
2024-10-04 14:19:45 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def create_gapfilled_record(prev_record, date)
|
|
|
|
new_record = prev_record.class.new(prev_record.attributes.except("id", "created_at", "updated_at"))
|
|
|
|
new_record.date = date
|
|
|
|
new_record.save! if cache
|
|
|
|
new_record
|
|
|
|
end
|
|
|
|
end
|