Fetch reciprocal exchange rates when syncing market data (#358)

* Fetch reciprocal exchange rates in sync

* Fix variable
This commit is contained in:
Jakub Kottnauer
2025-11-20 19:50:22 +01:00
committed by GitHub
parent 6decd6eaca
commit e50a5792a0
4 changed files with 48 additions and 2 deletions

View File

@@ -35,6 +35,7 @@ class Account::MarketDataImporterTest < ActiveSupport::TestCase
# Seed a rate for the first required day so that the importer only needs the next day forward
existing_date = account.start_date
ExchangeRate.create!(from_currency: "CAD", to_currency: "USD", date: existing_date, rate: 2.0)
ExchangeRate.create!(from_currency: "USD", to_currency: "CAD", date: existing_date, rate: 0.5)
expected_start_date = (existing_date + 1.day) - PROVIDER_BUFFER
end_date = Date.current.in_time_zone("America/New_York").to_date
@@ -48,11 +49,20 @@ class Account::MarketDataImporterTest < ActiveSupport::TestCase
OpenStruct.new(from: "CAD", to: "USD", date: existing_date, rate: 1.5)
]))
@provider.expects(:fetch_exchange_rates)
.with(from: "USD",
to: "CAD",
start_date: expected_start_date,
end_date: end_date)
.returns(provider_success_response([
OpenStruct.new(from: "USD", to: "CAD", date: existing_date, rate: 0.67)
]))
before = ExchangeRate.count
Account::MarketDataImporter.new(account).import_all
after = ExchangeRate.count
assert_operator after, :>, before, "Should insert at least one new exchange-rate row"
assert_operator after, :>, before + 1, "Should insert at least two new exchange-rate rows"
end
test "syncs security prices for securities traded by the account" do
@@ -169,6 +179,7 @@ class Account::MarketDataImporterTest < ActiveSupport::TestCase
# Seed a rate for the first required day
existing_date = account.start_date
ExchangeRate.create!(from_currency: "CAD", to_currency: "USD", date: existing_date, rate: 2.0)
ExchangeRate.create!(from_currency: "USD", to_currency: "CAD", date: existing_date, rate: 0.5)
expected_start_date = (existing_date + 1.day) - PROVIDER_BUFFER
end_date = Date.current.in_time_zone("America/New_York").to_date
@@ -183,6 +194,15 @@ class Account::MarketDataImporterTest < ActiveSupport::TestCase
Provider::TwelveData::Error.new("Rate limit exceeded", details: { code: 429, message: "Rate limit exceeded" })
))
@provider.expects(:fetch_exchange_rates)
.with(from: "USD",
to: "CAD",
start_date: expected_start_date,
end_date: end_date)
.returns(provider_error_response(
Provider::TwelveData::Error.new("Rate limit exceeded", details: { code: 429, message: "Rate limit exceeded" })
))
before = ExchangeRate.count
# Should not raise an error, just log and continue

View File

@@ -34,6 +34,11 @@ class MarketDataImporterTest < ActiveSupport::TestCase
date: SNAPSHOT_START_DATE,
rate: 2.0)
ExchangeRate.create!(from_currency: "USD",
to_currency: "CAD",
date: SNAPSHOT_START_DATE,
rate: 0.5)
expected_start_date = (SNAPSHOT_START_DATE + 1.day) - PROVIDER_BUFFER
end_date = Date.current.in_time_zone("America/New_York").to_date
@@ -46,11 +51,20 @@ class MarketDataImporterTest < ActiveSupport::TestCase
OpenStruct.new(from: "CAD", to: "USD", date: SNAPSHOT_START_DATE, rate: 1.5)
]))
@provider.expects(:fetch_exchange_rates)
.with(from: "USD",
to: "CAD",
start_date: expected_start_date,
end_date: end_date)
.returns(provider_success_response([
OpenStruct.new(from: "USD", to: "CAD", date: SNAPSHOT_START_DATE, rate: 0.67)
]))
before = ExchangeRate.count
MarketDataImporter.new(mode: :snapshot).import_exchange_rates
after = ExchangeRate.count
assert_operator after, :>, before, "Should insert at least one new exchange-rate row"
assert_operator after, :>, before + 1, "Should insert at least two new exchange-rate rows"
end
test "syncs security prices" do