2025-02-28 11:35:10 -05:00
|
|
|
module Security::Provided
|
|
|
|
extend ActiveSupport::Concern
|
|
|
|
|
|
|
|
class_methods do
|
|
|
|
def provider
|
2025-03-17 11:54:53 -04:00
|
|
|
Providers.synth
|
2025-02-28 11:35:10 -05:00
|
|
|
end
|
|
|
|
|
2025-03-17 11:54:53 -04:00
|
|
|
def search_provider(symbol, country_code: nil, exchange_operating_mic: nil)
|
|
|
|
return [] if symbol.blank? || symbol.length < 2
|
2025-03-05 09:30:47 -05:00
|
|
|
|
2025-03-17 11:54:53 -04:00
|
|
|
response = provider.search_securities(symbol, country_code: country_code, exchange_operating_mic: exchange_operating_mic)
|
2025-02-28 11:35:10 -05:00
|
|
|
|
|
|
|
if response.success?
|
2025-03-17 11:54:53 -04:00
|
|
|
response.data.securities
|
2025-02-28 11:35:10 -05:00
|
|
|
else
|
|
|
|
[]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2025-03-17 11:54:53 -04:00
|
|
|
|
|
|
|
def sync_provider_prices(start_date:, end_date: Date.current)
|
|
|
|
unless has_prices?
|
|
|
|
Rails.logger.warn("Security id=#{id} ticker=#{ticker} is not known by provider, skipping price sync")
|
|
|
|
return 0
|
|
|
|
end
|
|
|
|
|
|
|
|
unless provider.present?
|
|
|
|
Rails.logger.warn("No security provider configured, cannot sync prices for id=#{id} ticker=#{ticker}")
|
|
|
|
return 0
|
|
|
|
end
|
|
|
|
|
|
|
|
response = provider.fetch_security_prices(self, start_date: start_date, end_date: end_date)
|
|
|
|
|
|
|
|
unless response.success?
|
|
|
|
Rails.logger.error("Provider error for sync_provider_prices with id=#{id} ticker=#{ticker}: #{response.error}")
|
|
|
|
return 0
|
|
|
|
end
|
|
|
|
|
|
|
|
fetched_prices = response.data.prices.map do |price|
|
|
|
|
price.attributes.slice("security_id", "date", "price", "currency")
|
|
|
|
end
|
|
|
|
|
|
|
|
Security::Price.upsert_all(fetched_prices, unique_by: %i[security_id date currency])
|
|
|
|
end
|
|
|
|
|
|
|
|
def find_or_fetch_price(date: Date.current, cache: true)
|
|
|
|
price = prices.find_by(date: date)
|
|
|
|
|
|
|
|
return price if price.present?
|
|
|
|
|
|
|
|
response = provider.fetch_security_price(self, date: date)
|
|
|
|
|
|
|
|
return nil unless response.success? # Provider error
|
|
|
|
|
|
|
|
price = response.data.price
|
|
|
|
price.save! if cache
|
|
|
|
price
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
def provider
|
|
|
|
self.class.provider
|
|
|
|
end
|
2025-02-28 11:35:10 -05:00
|
|
|
end
|