Files
sure/app/models/ibkr_account/data_helpers.rb
Gian-Reto Tarnutzer ce5d7dd736 Add Interactive Brokers Provider (#1722)
* Display multi-currency holdings correctly

* Implement IBKR provider

* Fix: Use historical exchange rate for historical prices

* Add brokerage exchange rate for trades

* Sync historical balances from IBKR

* Add logos in activity history

* Fix privacy mode blur in account view

* Improve IBKR XML Flex report parser errors
2026-05-12 23:45:19 +02:00

79 lines
2.0 KiB
Ruby

module IbkrAccount::DataHelpers
extend ActiveSupport::Concern
private
def parse_decimal(value)
return nil if value.nil?
normalized = value.is_a?(String) ? value.delete(",").strip : value.to_s
return nil if normalized.blank? || normalized == "-"
BigDecimal(normalized)
rescue ArgumentError
nil
end
def parse_date(value)
return nil if value.blank?
case value
when Date
value
when Time, DateTime, ActiveSupport::TimeWithZone
value.to_date
else
normalized = value.to_s.tr(";", " ")
Time.zone.parse(normalized)&.to_date || Date.parse(normalized)
end
rescue ArgumentError, TypeError
nil
end
def parse_datetime(value)
return nil if value.blank?
case value
when Time, DateTime, ActiveSupport::TimeWithZone
value.in_time_zone
when Date
value.in_time_zone
else
Time.zone.parse(value.to_s.tr(";", " "))
end
rescue ArgumentError, TypeError
nil
end
def resolve_security(row)
data = row.with_indifferent_access
ticker = data[:symbol].to_s.strip.upcase
return nil if ticker.blank?
Security.find_by(ticker: ticker) || create_security_from_row(ticker)
rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique
Security.find_by(ticker: ticker)
end
def trade_date_for(row)
data = row.with_indifferent_access
parsed_trade_date = parse_date(data[:trade_date])
return parsed_trade_date if parsed_trade_date
Rails.logger.warn(
"IbkrAccount::DataHelpers - Missing or invalid trade_date, falling back to Date.current. " \
"trade_id=#{data[:trade_id].inspect}"
)
Date.current
end
def extract_currency(row, fallback: nil)
value = row.with_indifferent_access[:currency]
value.present? ? value.to_s.upcase : fallback
end
def create_security_from_row(ticker)
Security.create!(ticker: ticker, name: ticker)
end
end