we-promise/sure · error · Provider::TwelveData::InvalidSecurityPriceError
No prices found for security #{symbol} on date #{date}
Error message
No prices found for security #{symbol} on date #{date} What it means
Provider::TwelveData::InvalidSecurityPriceError raised in fetch_security_price when the underlying fetch_security_prices call for a single-day range (start_date == end_date) succeeded but produced zero usable Price rows. Either values came back empty for that date or every close was nil/<= 0 and got filtered out.
Source
Thrown at app/models/provider/twelve_data.rb:204
SecurityInfo.new(
symbol: symbol,
name: profile.dig("name"),
links: profile.dig("website"),
logo_url: logo.dig("url"),
description: profile.dig("description"),
kind: profile.dig("type"),
exchange_operating_mic: exchange_operating_mic
)
end
end
def fetch_security_price(symbol:, exchange_operating_mic: nil, date:)
with_provider_response do
historical_data = fetch_security_prices(symbol:, exchange_operating_mic:, start_date: date, end_date: date)
raise historical_data.error if historical_data.error.present?
raise InvalidSecurityPriceError, "No prices found for security #{symbol} on date #{date}" if historical_data.data.blank?
historical_data.data.first
end
end
def fetch_security_prices(symbol:, exchange_operating_mic: nil, start_date:, end_date:)
with_provider_response do
throttle_request
response = client.get("#{base_url}/time_series") do |req|
req.params["symbol"] = symbol
req.params["mic_code"] = exchange_operating_mic
req.params["start_date"] = start_date.to_s
req.params["end_date"] = end_date.to_s
req.params["interval"] = "1day"
end
parsed = JSON.parse(response.body)
check_api_error!(parsed)View on GitHub (pinned to e69894adb9)
Solutions
- Check whether the date is a trading day for that exchange (weekends/holidays have no daily bar)
- Widen the window: call fetch_security_prices with start_date a few days earlier and pick the latest bar <= target date, instead of the exact-date helper
- Verify the symbol is still valid via search_securities / fetch_security_info; rename mappings go stale
- For listing-date issues, confirm the security existed on the requested date
Example fix
// before
price = provider.fetch_security_price(symbol: "AAPL", exchange_operating_mic: "XNAS", date: Date.new(2026, 8, 16)) # Sunday
// after
begin
price = provider.fetch_security_price(symbol: "AAPL", exchange_operating_mic: "XNAS", date: date)
rescue Provider::TwelveData::InvalidSecurityPriceError
prices = provider.fetch_security_prices(symbol: "AAPL", exchange_operating_mic: "XNAS", start_date: date - 5.days, end_date: date).data
price = prices.select { |p| p.date <= date }.max_by(&:date)
end Defensive patterns
Strategy: fallback
Validate before calling
trading_day = date trading_day -= 1 while trading_day.wday == 0 || trading_day.wday == 6 # cheap weekend check price = provider.fetch_security_price(symbol:, exchange_operating_mic:, date: trading_day)
Try / catch
begin
provider.fetch_security_price(symbol:, exchange_operating_mic:, date:)
rescue Provider::TwelveData::InvalidSecurityPriceError
prices = provider.fetch_security_prices(symbol:, exchange_operating_mic:, start_date: date - 7.days, end_date: date).data
prices.select { |p| p.date <= date }.max_by(&:date)
end Prevention
- Prefer range fetch + 'latest bar on or before date' over exact-date fetches
- Skip non-trading dates (weekends/holidays per exchange calendar) before requesting
- Verify symbols still exist before backfilling old dates
When it happens
Trigger: Requesting a price for a date the market was closed (weekend/holiday), a date before the security listed, or a delisted symbol; requesting a date in a timezone such that Twelve Data has no daily bar; all closes filtered by the price<=0 guard.
Common situations: Valuing a portfolio 'as of Sunday'; backfilling historical prices before an IPO date; ticker renamed (TWTR → X) so the old symbol has no data.
Related errors
- API error (code: #{error_code}): #{error_message}
- 429
- API error (code: #{parsed["code"]}): #{parsed["message"] ||
- No exchange rate found for #{from}/#{to} on or before #{date
- Failed to fetch security prices: #{prices_response.error.mes
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/4b090f2fb3c5a777.
Report an issue: GitHub.