mirror of
https://github.com/we-promise/sure.git
synced 2026-04-07 14:31:25 +00:00
* FIX issue with stock price retrieval on weekend * make weekend provisional and increase lookback * FIX query error * fix gap fill The bug: When a price is provisional but the provider doesn't return a new value (weekends), we fall back to the existing DB value instead of gap-filling from Friday's correct price. * Update importer.rb Align provider fetch to use PROVISIONAL_LOOKBACK_DAYS for consistency. In the DB fallback, derive currency from provider_prices or db_prices and filter the query accordingly. * Update 20260110122603_mark_suspicious_prices_provisional.rb * Delete db/migrate/20260110122603_mark_suspicious_prices_provisional.rb Signed-off-by: soky srm <sokysrm@gmail.com> * Update importer.rb * FIX tests * FIX last tests * Update importer_test.rb The test doesn't properly force effective_start_date to skip old dates because there are many missing dates between the old date and recent dates. Let me fix it to properly test the subset processing scenario. --------- Signed-off-by: soky srm <sokysrm@gmail.com>
101 lines
3.7 KiB
Ruby
101 lines
3.7 KiB
Ruby
require "test_helper"
|
|
require "ostruct"
|
|
|
|
class MarketDataImporterTest < ActiveSupport::TestCase
|
|
include ProviderTestHelper
|
|
|
|
SNAPSHOT_START_DATE = MarketDataImporter::SNAPSHOT_DAYS.days.ago.to_date
|
|
SECURITY_PRICE_BUFFER = Security::Price::Importer::PROVISIONAL_LOOKBACK_DAYS.days
|
|
EXCHANGE_RATE_BUFFER = 5.days
|
|
|
|
setup do
|
|
Security::Price.delete_all
|
|
ExchangeRate.delete_all
|
|
Trade.delete_all
|
|
Holding.delete_all
|
|
Security.delete_all
|
|
|
|
@provider = mock("provider")
|
|
Provider::Registry.any_instance
|
|
.stubs(:get_provider)
|
|
.with(:twelve_data)
|
|
.returns(@provider)
|
|
end
|
|
|
|
test "syncs required exchange rates" do
|
|
family = Family.create!(name: "Smith", currency: "USD")
|
|
family.accounts.create!(name: "Chequing",
|
|
currency: "CAD",
|
|
balance: 100,
|
|
accountable: Depository.new)
|
|
|
|
# Seed stale rate so only the next missing day is fetched
|
|
ExchangeRate.create!(from_currency: "CAD",
|
|
to_currency: "USD",
|
|
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) - EXCHANGE_RATE_BUFFER
|
|
end_date = Date.current.in_time_zone("America/New_York").to_date
|
|
|
|
@provider.expects(:fetch_exchange_rates)
|
|
.with(from: "CAD",
|
|
to: "USD",
|
|
start_date: expected_start_date,
|
|
end_date: end_date)
|
|
.returns(provider_success_response([
|
|
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 + 1, "Should insert at least two new exchange-rate rows"
|
|
end
|
|
|
|
test "syncs security prices" do
|
|
security = Security.create!(ticker: "AAPL", exchange_operating_mic: "XNAS")
|
|
|
|
expected_start_date = SNAPSHOT_START_DATE - SECURITY_PRICE_BUFFER
|
|
end_date = Date.current.in_time_zone("America/New_York").to_date
|
|
|
|
@provider.expects(:fetch_security_prices)
|
|
.with(symbol: security.ticker,
|
|
exchange_operating_mic: security.exchange_operating_mic,
|
|
start_date: expected_start_date,
|
|
end_date: end_date)
|
|
.returns(provider_success_response([
|
|
OpenStruct.new(security: security,
|
|
date: SNAPSHOT_START_DATE,
|
|
price: 100,
|
|
currency: "USD")
|
|
]))
|
|
|
|
@provider.stubs(:fetch_security_info)
|
|
.with(symbol: "AAPL", exchange_operating_mic: "XNAS")
|
|
.returns(provider_success_response(OpenStruct.new(name: "Apple", logo_url: "logo")))
|
|
|
|
# Ignore exchange rate calls for this test
|
|
@provider.stubs(:fetch_exchange_rates).returns(provider_success_response([]))
|
|
|
|
MarketDataImporter.new(mode: :snapshot).import_security_prices
|
|
|
|
assert_equal 1, Security::Price.where(security: security, date: SNAPSHOT_START_DATE).count
|
|
end
|
|
end
|