HKUDS/Vibe-Trading · error · MissingExchangeRateError
no {base}/{self.quote_currency} rate on or before {day}{boun
Error message
no {base}/{self.quote_currency} rate on or before {day}{bound} What it means
Even with allow_stale=True, get_rate needs at least one quote for the base currency on or before the requested day, and within max_staleness_days if provided. No candidate exists -> MissingExchangeRateError, with the staleness bound included in the message when relevant.
Source
Thrown at agent/src/entities/cashflow.py:677
"never applied silently"
)
candidates = [
entry
for (entry_base, entry_date), entry in self.rates.items()
if entry_base == base and entry_date <= day
]
if max_staleness_days is not None:
candidates = [
entry
for entry in candidates
if (day - entry.date).days <= max_staleness_days
]
if not candidates:
bound = (
f" within {max_staleness_days} days" if max_staleness_days is not None else ""
)
raise MissingExchangeRateError(
f"no {base}/{self.quote_currency} rate on or before {day}{bound}"
)
best = max(candidates, key=lambda entry: entry.date)
return best, True
def translate_cashflows(
flows: CashFlowSeries | Iterable[CashFlow],
rate_table: FxRateTable,
*,
allow_stale_rates: bool = False,
max_staleness_days: int | None = None,
) -> CashFlowSeries:
"""Convert flows in one or more currencies into ``rate_table``'s currency.
Each flow is converted using the FX rate quoted on **that flow's own
settlement date** -- never a single series-level or period-end rate.
Applying one end-of-period rate to every flow is the most commonView on GitHub (pinned to 80ffdda44c)
Solutions
- Source earlier rates covering the requested period and rebuild the table
- Increase max_staleness_days to a tolerance appropriate for the currency's quote frequency
- Remove or relax the bound (pass None) if some staleness is acceptable for your use case
Example fix
# before
rate, stale = table.get_rate('EUR', d, allow_stale=True, max_staleness_days=3)
# after
rate, stale = table.get_rate('EUR', d, allow_stale=True, max_staleness_days=10) Defensive patterns
Strategy: fallback
Validate before calling
earliest = min(e.date for k, e in table.rates.items() if k[0] == base)
if day < earliest:
raise ValueError('need earlier FX history') Try / catch
from agent.src.entities.cashflow import MissingExchangeRateError
try:
rate, stale = table.get_rate(base, day, allow_stale=True, max_staleness_days=N)
except MissingExchangeRateError:
rate = fetch_rate_from_api(base, day) # backfill then rebuild table Prevention
- Backfill FX history to before your earliest flow
- Size max_staleness_days to the currency's quote frequency
- Alert when requested dates approach the table's earliest quote
When it happens
Trigger: get_rate('EUR', date(2024,1,31), allow_stale=True) when the table's earliest EUR quote is 2024-02-05; or a candidate exists but is 10 days old with max_staleness_days=7.
Common situations: Rates feed starting later than the flow history (backfilling old periods); a thinly quoted currency where gaps exceed your staleness tolerance; max_staleness_days set too tight for weekly-quoted currencies.
Related errors
- no {base}/{self.quote_currency} rate for {day}; pass allow_s
- rate must be numeric, got {self.rate!r}
- rate must be finite and strictly positive -- it is quote-per
- FxRateTable entries must be FxRate, got {type(entry).__name_
- FxRate {entry.base_currency}/{entry.quote_currency}@{entry.d
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/040c78c18555f70f.
Report an issue: GitHub.