HKUDS/Vibe-Trading · error · ValueError
start_date ({start}) > end_date ({end})
Error message
start_date ({start}) > end_date ({end}) What it means
After parsing, _parse_period checks that the start is not after the end (mirroring backtest loaders.validate_date_range). Inverted ranges are rejected because forward returns and IC computation are undefined for them.
Source
Thrown at agent/src/tools/alpha_bench_tool.py:97
def _parse_period(period: str) -> tuple[str, str]:
"""Return (start_date, end_date) as YYYY-MM-DD strings."""
if not isinstance(period, str):
raise ValueError(f"period must be string, got {type(period).__name__}")
m = _PERIOD_DATE.match(period)
if m:
start, end = m.group(1), m.group(2)
else:
m = _PERIOD_YEAR.match(period)
if m:
start, end = f"{m.group(1)}-01-01", f"{m.group(2)}-12-31"
else:
raise ValueError(
f"period {period!r} must be YYYY-YYYY or YYYY-MM-DD/YYYY-MM-DD"
)
# Match backtest loaders.validate_date_range: reject inverted ranges.
if pd.Timestamp(start) > pd.Timestamp(end):
raise ValueError(f"start_date ({start}) > end_date ({end})")
return start, end
def _load_universe_panel(
universe: str, period: str, *, use_cache: bool = True
) -> dict[str, pd.DataFrame]:
"""Load OHLCV(+amount, +vwap) wide panel for the requested universe.
Returns a dict keyed by panel column (open/high/low/close/volume/amount/vwap)
where each value is a wide ``pd.DataFrame`` indexed by date (DatetimeIndex)
with one column per instrument.
Args:
universe: ``csi300`` | ``sp500`` | ``btc-usdt``.
period: ``YYYY-YYYY`` or ``YYYY-MM-DD/YYYY-MM-DD``.
use_cache: When True (default) reuse a pickle in
``~/.vibe-trading/cache/`` if the same universe+period was fetched
before. Set to False to force a re-fetch.View on GitHub (pinned to 80ffdda44c)
Solutions
- Swap the two dates so the earlier one comes first
- Validate ordering at the call site before invoking the tool
- Sort the pair: start, end = sorted([d1, d2]) for date inputs
Example fix
// before
period = f'{end:%Y-%m-%d}/{start:%Y-%m-%d}'
// after
period = f'{start:%Y-%m-%d}/{end:%Y-%m-%d}' Defensive patterns
Strategy: validation
Validate before calling
if _PERIOD_YEAR.match(period):
a, b = sorted(period.split('-')); period = f'{a}-{b}'
elif '/' in period:
s, e = period.split('/'); period = f'{min(s,e)}_noop' if False else '/'.join(sorted([s, e])) Type guard
def ordered_period(p: str) -> str:
if '-' in p and '/' not in p:
a, b = sorted(p.split('-')); return f'{a}-{b}'
s, e = sorted(p.split('/')); return f'{s}/{e}' Try / catch
try:
_parse_period(period)
except ValueError as e:
if 'start_date' in str(e) and '>' in str(e):
period = ordered_period(period) # swap and retry Prevention
- Sort date pairs at the UI boundary
- Unit-test boundary periods (equal dates, year edges)
When it happens
Trigger: Passing '2023-2020' or '2023-01-01/2020-12-31' as the period; swapping start/end when building the string programmatically.
Common situations: UIs that let users enter dates in either order; date-range pickers returning (end, start); off-by-one parameter swaps in wrapper scripts.
Related errors
- maturity_date {self.maturity_date} precedes inception_date {
- period must be string, got {type(period).__name__}
- period {period!r} must be YYYY-YYYY or YYYY-MM-DD/YYYY-MM-DD
- universe {universe!r} not recognized; expected one of {sorte
- universe {universe!r} produced empty panel for {start}..{end
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/50bf8e7eeb37b7ef.
Report an issue: GitHub.