How to Configure start_date and end_date for Historical Analysis in AI Hedge Fund

To configure historical analysis windows in the AI Hedge Fund project, pass --start-date and --end-date arguments via CLI or set them directly when initializing the BacktestEngine class, which propagates these values through date resolution, back-testing loops, and API data fetching.

The virattt/ai-hedge-fund repository implements a unified date-handling pipeline that controls historical data retrieval and simulation periods. Configuring start_date and end_date for historical analysis allows you to define precise back-testing windows, whether running simulations from the command line or embedding the engine in custom Python workflows.

CLI Argument Parsing and Date Resolution

The entry point for date configuration begins in src/cli/input.py, where the resolve_dates function handles validation and defaults for the --start-date and --end-date flags.

When parse_cli_inputs is invoked, it calls resolve_dates to:

  1. Validate date strings against the YYYY-MM-DD format using datetime.strptime.
  2. Default end_date to the current date if omitted.
  3. Calculate start_date by subtracting a configurable number of months (default 3) from the end date when not provided.

# src/cli/input.py – resolve_dates implementation

def resolve_dates(start_date: str | None, end_date: str | None, *, default_months_back: int | None = None) -> tuple[str, str]:
    if start_date:
        datetime.strptime(start_date, "%Y-%m-%d")      # validation

    if end_date:
        datetime.strptime(end_date, "%Y-%m-%d")        # validation

    final_end = end_date or datetime.now().strftime("%Y-%m-%d")
    if start_date:
        final_start = start_date
    else:
        months = default_months_back if default_months_back is not None else 3
        final_start = (datetime.strptime(final_end, "%Y-%m-%d") - relativedelta(months=months)).strftime("%Y-%m-%d")
    return final_start, final_end

The function returns a tuple of ISO-formatted date strings that populate the CLIInputs dataclass for downstream consumption.

Entry Point Propagation

In src/main.py, the parsed dates flow from the CLI layer into the back-testing engine constructor. The main function instantiates the Backtester class with the resolved start and end dates, establishing the simulation horizon before any data fetching occurs.


# src/main.py – main entry point

inputs = parse_cli_inputs(...)
backtester = Backtester(
    tickers=inputs.tickers,
    start_date=inputs.start_date,
    end_date=inputs.end_date,
    ...
)

This ensures that the entire analysis pipeline operates within the specified temporal bounds, from initial data prefetch through final portfolio valuation.

Back-Testing Engine Implementation

The BacktestEngine class in src/backtesting/engine.py receives start_date and end_date as constructor parameters, storing them as self._start_date and self._end_date. These values drive two critical operations:

  • Data Prefetching: Loading historical price data for the full window before simulation begins.
  • Simulation Loop: Iterating over business days using pd.date_range to generate the analysis timeline.

# src/backtesting/engine.py – simulation loop

dates = pd.date_range(self._start_date, self._end_date, freq="B")
for current_date in dates:
    lookback_start = (current_date - relativedelta(months=1)).strftime("%Y-%m-%d")
    # agents receive lookback_start … current_date as their analysis window

During each iteration, agents analyze data within a rolling lookback window relative to the current simulation date, but the overall simulation respects the global start and end boundaries.

Data Retrieval Layer

All external API calls in src/tools/api.py accept the configured date parameters to ensure consistent data windows. The get_prices function and related endpoints use these dates to construct cache keys and HTTP request URLs.


# src/tools/api.py – price fetching with date parameters

def get_prices(ticker: str, start_date: str, end_date: str, api_key: str = None) -> list[Price]:
    cache_key = f"{ticker}_{start_date}_{end_date}"
    url = f"https://api.financialdatasets.ai/prices/?ticker={ticker}&interval=day&start_date={start_date}&end_date={end_date}"
    # ...

Similarly, get_insider_trades and get_company_news accept start_date parameters to filter historical records, ensuring that analysis agents only receive data relevant to the configured historical analysis window.

Practical Configuration Examples

Command-Line Execution

Run a back-test for a specific three-month window by passing explicit date flags:

poetry run python src/main.py \
    --ticker AAPL,MSFT,NVDA \
    --start-date 2024-01-01 \
    --end-date 2024-04-01

Omitting --end-date defaults to today; omitting --start-date defaults to three months before the end date.

Programmatic Back-Testing

Initialize the engine directly in Python for custom workflows:

from src.backtesting.engine import BacktestEngine

engine = BacktestEngine(
    agent=my_agent,
    tickers=["AAPL", "MSFT"],
    start_date="2023-06-01",
    end_date="2023-12-31",
    initial_capital=100_000,
    model_name="gpt-4o",
    model_provider="openai",
    selected_analysts=None,
    initial_margin_requirement=0.0,
)

metrics = engine.run_backtest()
print(metrics)

Standalone Data Fetching

Retrieve historical price data outside the back-testing context using the same date parameters:

from src.tools.api import get_price_data

df = get_price_data("AAPL", start_date="2022-01-01", end_date="2022-12-31")
print(df.head())

Summary

  • Date validation occurs in src/cli/input.py via resolve_dates, which enforces YYYY-MM-DD formatting and calculates sensible defaults.
  • Date propagation flows from CLI parsing in src/main.py through to the BacktestEngine constructor, ensuring consistent temporal boundaries.
  • Simulation scope is controlled by pd.date_range(self._start_date, self._end_date, freq="B") in the back-testing engine, iterating only over business days within the window.
  • Data consistency is maintained across src/tools/api.py functions, where start_date and end_date parameters filter all external API requests and cache keys.

Frequently Asked Questions

What date format does the AI Hedge Fund project require?

The system requires dates in YYYY-MM-DD format (ISO 8601). The resolve_dates function in src/cli/input.py validates input strings using datetime.strptime(date_string, "%Y-%m-%d") and raises a ValueError if the format is invalid.

What happens if I omit the start_date or end_date parameters?

If --end-date is omitted, the system defaults to the current date. If --start-date is omitted, the system calculates a default by subtracting three months (or a configurable default_months_back value) from the resolved end date, as implemented in the resolve_dates function.

Can I configure custom date windows when using the BacktestEngine programmatically?

Yes. When instantiating BacktestEngine directly, pass start_date and end_date as string arguments to the constructor. These values override any CLI defaults and control both the data prefetching phase and the main simulation loop defined in src/backtesting/engine.py.

How does the date range affect data fetching performance?

The date range directly determines the volume of data retrieved from external APIs. The engine calls get_prices, get_insider_trades, and get_company_news with the full start_date to end_date window, so wider ranges increase API call duration and memory usage for the prefetch cache.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →