we-promise/sure · warning · Provider::TinkoffInvest::InvalidSecurityPriceError
No T-Invest price for #{symbol} on #{date}
Error message
No T-Invest price for #{symbol} on #{date} What it means
fetch_security_price delegates to fetch_security_prices for the single day and raises InvalidSecurityPriceError when the result set is empty -- no candles and no live price existed for that instrument on that date. For T-Invest this typically means a non-trading day (MOEX weekend/holiday), a date before the instrument listed, or a suspended board. The rescue-free raise distinguishes 'we got data but not for this date' from instrument resolution failures.
Source
Thrown at app/models/provider/tinkoff_invest.rb:124
logo_url: logo_url(detail.dig("brand", "logoName")),
description: nil,
kind: surfaced_kind(short["instrumentType"]),
exchange_operating_mic: mic_for(short["classCode"], detail["exchange"])
)
end
end
def fetch_security_price(symbol:, exchange_operating_mic:, date:)
with_provider_response do
historical = fetch_security_prices(
symbol: symbol,
exchange_operating_mic: exchange_operating_mic,
start_date: date,
end_date: date
)
raise historical.error if historical.error.present?
raise InvalidSecurityPriceError, "No T-Invest price for #{symbol} on #{date}" if historical.data.blank?
historical.data.find { |p| p.date == date } ||
historical.data.select { |p| p.date <= date }.max_by(&:date) ||
historical.data.first
end
end
def fetch_security_prices(symbol:, exchange_operating_mic:, start_date:, end_date:)
with_provider_response do
short = resolve_short(symbol, exchange_operating_mic)
raise Error, "Unknown T-Invest instrument: #{symbol}" if short.nil?
uid = short["uid"]
bond = short["instrumentType"].to_s == "bond"
currency = short["currency"].to_s.upcase
mic = mic_for(short["classCode"], short["exchange"])
# Bonds quote in % of par; multiply by nominal to get a money price. AView on GitHub (pinned to e69894adb9)
Solutions
- Validate the date against MOEX trading calendar / walk back to the previous trading day before calling
- For 'today' prices, tolerate lag: retry shortly after session open or use the previous close explicitly
- Confirm the instrument has any history at all via fetch_security_prices over a wide range
Example fix
# before price = provider.fetch_security_price(symbol: sym, exchange_operating_mic: mic, date: date) # after begin price = provider.fetch_security_price(symbol: sym, exchange_operating_mic: mic, date: date) rescue Provider::TinkoffInvest::InvalidSecurityPriceError date = MoexTradingCalendar.previous_trading_day(date) retry end
Defensive patterns
Strategy: fallback
Validate before calling
# MOEX trades Mon-Fri; verify holidays before exact-date pricing date = MoexTradingCalendar.previous_trading_day(date) unless MoexTradingCalendar.trading_day?(date)
Try / catch
begin price = provider.fetch_security_price(symbol:, exchange_operating_mic:, date:) rescue Provider::TinkoffInvest::InvalidSecurityPriceError price = security.last_known_price # degrade to previous valuation end
Prevention
- Query ranges and select the wanted date client-side, matching the method's own fallback logic
- Avoid 'today' price queries before the session's data lands; schedule valuation after market close
When it happens
Trigger: fetch_security_price(symbol: 'SBER', exchange_operating_mic: 'XMOS', date: <Saturday or MOEX holiday>) returns an empty historical.data; also early-morning calls where the candle feed lags and the live-price append hasn't produced a row for today yet; dates before listing.
Common situations: Valuation jobs running on Moscow-exchange holidays not in the app's holiday calendar; 'price as of today' queries fired before session data lands; newly listed bonds with no candle history yet.
Related errors
- No prices found for security #{symbol} on date #{date}
- Missing or invalid T-Invest bond nominal for #{symbol}
- No prices found for security #{symbol} on date #{date}
- Unknown T-Invest instrument: #{symbol}
- Could not sign in with that passkey. Please try again or use
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/59a5abd1927d6012.
Report an issue: GitHub.