{"record":{"id":"4b090f2fb3c5a777","repo":"we-promise/sure","slug":"no-prices-found-for-security-symbol-on-date-d-4b090f","errorCode":null,"errorMessage":"No prices found for security #{symbol} on date #{date}","messagePattern":"No prices found for security #(.+?) on date #(.+?)","errorType":"exception","errorClass":"Provider::TwelveData::InvalidSecurityPriceError","httpStatus":null,"severity":"error","filePath":"app/models/provider/twelve_data.rb","lineNumber":204,"sourceCode":"\n      SecurityInfo.new(\n        symbol: symbol,\n        name: profile.dig(\"name\"),\n        links: profile.dig(\"website\"),\n        logo_url: logo.dig(\"url\"),\n        description: profile.dig(\"description\"),\n        kind: profile.dig(\"type\"),\n        exchange_operating_mic: exchange_operating_mic\n      )\n    end\n  end\n\n  def fetch_security_price(symbol:, exchange_operating_mic: nil, date:)\n    with_provider_response do\n      historical_data = fetch_security_prices(symbol:, exchange_operating_mic:, start_date: date, end_date: date)\n\n      raise historical_data.error if historical_data.error.present?\n      raise InvalidSecurityPriceError, \"No prices found for security #{symbol} on date #{date}\" if historical_data.data.blank?\n\n      historical_data.data.first\n    end\n  end\n\n  def fetch_security_prices(symbol:, exchange_operating_mic: nil, start_date:, end_date:)\n    with_provider_response do\n      throttle_request\n      response = client.get(\"#{base_url}/time_series\") do |req|\n        req.params[\"symbol\"] = symbol\n        req.params[\"mic_code\"] = exchange_operating_mic\n        req.params[\"start_date\"] = start_date.to_s\n        req.params[\"end_date\"] = end_date.to_s\n        req.params[\"interval\"] = \"1day\"\n      end\n\n      parsed = JSON.parse(response.body)\n      check_api_error!(parsed)","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/provider/twelve_data.rb#L186-L222","documentation":"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.","triggerScenarios":"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.","commonSituations":"Valuing a portfolio 'as of Sunday'; backfilling historical prices before an IPO date; ticker renamed (TWTR → X) so the old symbol has no data.","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"],"exampleFix":"// before\nprice = provider.fetch_security_price(symbol: \"AAPL\", exchange_operating_mic: \"XNAS\", date: Date.new(2026, 8, 16)) # Sunday\n\n// after\nbegin\n  price = provider.fetch_security_price(symbol: \"AAPL\", exchange_operating_mic: \"XNAS\", date: date)\nrescue Provider::TwelveData::InvalidSecurityPriceError\n  prices = provider.fetch_security_prices(symbol: \"AAPL\", exchange_operating_mic: \"XNAS\", start_date: date - 5.days, end_date: date).data\n  price = prices.select { |p| p.date <= date }.max_by(&:date)\nend","handlingStrategy":"fallback","validationCode":"trading_day = date\ntrading_day -= 1 while trading_day.wday == 0 || trading_day.wday == 6 # cheap weekend check\nprice = provider.fetch_security_price(symbol:, exchange_operating_mic:, date: trading_day)","typeGuard":null,"tryCatchPattern":"begin\n  provider.fetch_security_price(symbol:, exchange_operating_mic:, date:)\nrescue Provider::TwelveData::InvalidSecurityPriceError\n  prices = provider.fetch_security_prices(symbol:, exchange_operating_mic:, start_date: date - 7.days, end_date: date).data\n  prices.select { |p| p.date <= date }.max_by(&:date)\nend","preventionTips":["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"],"tags":["ruby","twelvedata","price-history","no-data","market-closed"],"backgroundTag":"no-historical-data-for-date","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}