# AI Hedge Fund Flow Execution Lifecycle: From CLI Input to Trading Decisions

> Explore the AI hedge fund flow execution lifecycle. Understand steps from CLI input to trading decisions, including LangGraph workflow, agent invocation, and trade execution for performance.

- Repository: [Virat Singh/ai-hedge-fund](https://github.com/virattt/ai-hedge-fund)
- Tags: how-to-guide
- Published: 2026-03-09

---

**The flow execution lifecycle in the virattt/ai-hedge-fund repository consists of seven distinct stages: input gathering, LangGraph workflow construction, agent invocation, decision normalization, trade execution, performance metrics calculation, and final output rendering.**

The virattt/ai-hedge-fund project orchestrates a complete end-to-end trading pipeline using LangGraph and LLM-driven agents. Understanding the flow execution lifecycle is essential for developers extending the system or debugging agent behavior. The lifecycle spans from command-line argument parsing through graph-based agent execution to final portfolio valuation and reporting.

## Stage 1: Input Gathering and CLI Parsing

The flow execution lifecycle begins in [`src/main.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/main.py) at the script entry point.

```python
if __name__ == "__main__":
    inputs = parse_cli_inputs(...)
    # Build the portfolio dict expected by the agents

    portfolio = {
        "cash": inputs.initial_cash,
        "margin_requirement": inputs.margin_requirement,
        ...
    }
    result = run_hedge_fund(...)
    print_trading_output(result)

```

The `parse_cli_inputs` function in [`src/cli/input.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/cli/input.py) reads command-line flags, validates date ranges, tickers, and optional graph visualization or reasoning flags. It returns a structured object that [`src/main.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/main.py) uses to construct a plain dictionary representing the initial **portfolio**, containing keys such as `cash` and `margin_requirement` required by downstream LangGraph agents.

## Stage 2: Workflow Construction with LangGraph

Once inputs are validated, `run_hedge_fund` calls `create_workflow` to assemble the agent graph.

```python
workflow = create_workflow(selected_analysts if selected_analysts else None)
agent = workflow.compile()

```

The `create_workflow` function in [`src/main.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/main.py) performs the following steps:

1. Instantiates a `StateGraph` with the shared `AgentState` schema.
2. Adds a **start node** (`start`) to initialize the state.
3. Dynamically injects analyst nodes (e.g., sentiment, fundamentals) retrieved from `get_analyst_nodes` in [`src/utils/analysts.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/utils/analysts.py).
4. Connects each analyst to the **risk-management** node, then to the **portfolio-management** node, and finally routes to the graph `END`.

This construction phase defines the flow execution topology before any LLM inference occurs.

## Stage 3: Agent Invocation and Graph Execution

With a compiled graph (`agent`), the system invokes the flow execution lifecycle core.

```python
final_state = agent.invoke({
    "messages": [HumanMessage(content="Make trading decisions...")],
    "data": {
        "tickers": tickers,
        "portfolio": portfolio,
        "start_date": start_date,
        "end_date": end_date,
        "analyst_signals": {},
    },
    "metadata": {
        "show_reasoning": show_reasoning,
        "model_name": model_name,
        "model_provider": model_provider,
    },
})

```

During invocation:

- Each **analyst node** enriches `data["analyst_signals"]` with ticker-specific insights.
- The **risk_management_agent** can veto or adjust signals based on portfolio constraints.
- The **portfolio_management_agent** produces a JSON-encoded decision string placed in `final_state["messages"][-1].content`.

This stage represents the primary LLM-driven computation phase of the flow execution lifecycle.

## Stage 4: Decision Normalization

When operating in back-test mode, raw LLM output undergoes normalization via `AgentController.run_agent` in [`src/backtesting/controller.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/backtesting/controller.py).

The controller:

- Guarantees a **snapshot** of the portfolio is sent to the agent for legacy compatibility.
- Extracts `decisions` and `analyst_signals` from the LLM response.
- Normalizes each ticker's decision to a concrete action (`buy`, `sell`, `short`, `cover`, `hold`) and a numeric quantity, coercing types and defaulting safely to prevent runtime errors during simulation.

## Stage 5: Trade Execution and Portfolio Valuation

The flow execution lifecycle branches based on execution mode.

### Live Mode

`TradeExecutor.execute_trade` in [`src/backtesting/trader.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/backtesting/trader.py) receives a ticker, action, quantity, price, and the current `Portfolio`. It maps actions to the appropriate portfolio method:

- `apply_long_buy`
- `apply_long_sell`
- `apply_short_open`
- `apply_short_cover`

### Back-test Mode

`BacktestEngine.run_backtest` in [`src/backtesting/engine.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/backtesting/engine.py) drives a daily simulation loop:

1. **Prefetch** market data for all tickers and SPY (benchmark).
2. Iterate over business days using `pd.date_range`.
3. Pull price data for the prior day; skip if missing.
4. Call `AgentController` to get normalized decisions.
5. Execute trades via `TradeExecutor`.
6. Compute portfolio value (`calculate_portfolio_value`) and exposures (`compute_exposures`).
7. Append a `PortfolioValuePoint` to the history.
8. Build a row of daily metrics (`OutputBuilder.build_day_rows`) and print the full table.
9. Compute final performance metrics (`PerformanceMetricsCalculator.compute_metrics`).

## Stage 6: Performance Metrics and Reporting

Following execution, the system calculates quantitative performance indicators. `PerformanceMetricsCalculator` in [`src/backtesting/metrics.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/backtesting/metrics.py) derives:

- Sharpe ratio
- Sortino ratio
- Maximum drawdown
- Long/short exposure ratios
- Gross and net exposures

`OutputBuilder` in [`src/backtesting/output.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/backtesting/output.py) formats these into markdown-style tables. For live executions, `print_trading_output` in [`src/utils/display.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/utils/display.py) renders decisions and analyst signals in a readable console format.

## Stage 7: Output Display and Final Rendering

The flow execution lifecycle concludes with structured output generation. `run_hedge_fund` returns a JSON-compatible dictionary:

```json
{
  "decisions": { ... },
  "analyst_signals": { ... }
}

```

`print_trading_output` in [`src/utils/display.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/utils/display.py) consumes this payload to print a human-readable summary, completing the end-to-end pipeline.

## Complete Code Examples

### Running the Hedge Fund CLI

Trigger the full flow execution lifecycle via command line:

```bash
python -m src.main \
  --tickers AAPL MSFT TSLA \
  --start-date 2024-01-01 \
  --end-date   2024-06-30 \
  --initial-cash 100000 \
  --margin-requirement 0.5 \
  --model-name gpt-4.1 \
  --model-provider OpenAI \
  --selected-analysts fundamentals sentiment

```

This command executes all seven stages, culminating in a printed table of daily trades and performance metrics.

### Back-Testing a Strategy Programmatically

Execute the flow execution lifecycle in historical simulation mode:

```python
from src.backtesting.engine import BacktestEngine
from src.agents.risk_manager import risk_management_agent

engine = BacktestEngine(
    agent=risk_management_agent,
    tickers=["AAPL", "MSFT", "TSLA"],
    start_date="2024-01-01",
    end_date="2024-06-30",
    initial_capital=100_000,
    model_name="gpt-4.1",
    model_provider="OpenAI",
    selected_analysts=["fundamentals", "sentiment"],
    initial_margin_requirement=0.5,
)

metrics = engine.run_backtest()
print("Final performance:", metrics)

```

The engine runs stages 1 through 6 in simulation, computing final performance metrics without live market exposure.

## Summary

The flow execution lifecycle in virattt/ai-hedge-fund follows a rigorous seven-stage pipeline:

- **Input Gathering**: CLI arguments parsed via [`src/cli/input.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/cli/input.py) and portfolio initialized in [`src/main.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/main.py)
- **Workflow Construction**: LangGraph assembly via `create_workflow` and `get_analyst_nodes` in [`src/main.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/main.py) and [`src/utils/analysts.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/utils/analysts.py)
- **Agent Invocation**: Graph execution via `agent.invoke` with state management across analyst, risk, and portfolio nodes
- **Decision Normalization**: LLM output coercion to deterministic actions via `AgentController` in [`src/backtesting/controller.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/backtesting/controller.py)
- **Trade Execution**: Live trades via `TradeExecutor` in [`src/backtesting/trader.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/backtesting/trader.py) or historical simulation via `BacktestEngine` in [`src/backtesting/engine.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/backtesting/engine.py)
- **Metrics Calculation**: Sharpe, Sortino, and drawdown computation in [`src/backtesting/metrics.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/backtesting/metrics.py)
- **Output Rendering**: Human-readable formatting via `print_trading_output` in [`src/utils/display.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/utils/display.py) and `OutputBuilder` in [`src/backtesting/output.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/backtesting/output.py)

## Frequently Asked Questions

### How does the flow execution lifecycle handle errors during agent invocation?

The system relies on LangGraph's built-in error handling during the `agent.invoke` call in [`src/main.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/main.py). If an analyst node fails, the error propagates through the graph state. For back-testing, the `BacktestEngine` in [`src/backtesting/engine.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/backtesting/engine.py) wraps daily iterations in logic that skips dates with missing market data, ensuring the flow execution lifecycle continues uninterrupted across valid trading days.

### What is the difference between live mode and back-test mode in the execution stage?

In **live mode**, the `TradeExecutor.execute_trade` method in [`src/backtesting/trader.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/backtesting/trader.py) applies decisions immediately to an in-memory `Portfolio` object using methods like `apply_long_buy` and `apply_short_open`. In **back-test mode**, the `BacktestEngine.run_backtest` method drives a historical simulation loop, prefetching market data, iterating over business days, and computing portfolio valuations retroactively without live market interaction.

### How are analyst signals aggregated during the workflow construction stage?

The `create_workflow` function in [`src/main.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/main.py) dynamically injects analyst nodes retrieved from `get_analyst_nodes` in [`src/utils/analysts.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/utils/analysts.py). Each analyst node writes its signals into the shared `AgentState` under `data["analyst_signals"]`. The graph topology ensures all analyst nodes route to the risk-management node, which reads the aggregated signals before passing them to the portfolio-management node for final decision synthesis.

### Where are performance metrics calculated in the flow execution lifecycle?

Performance metrics are calculated during **Stage 6** by the `PerformanceMetricsCalculator` class in [`src/backtesting/metrics.py`](https://github.com/virattt/ai-hedge-fund/blob/main/src/backtesting/metrics.py). This component computes the Sharpe ratio, Sortino ratio, maximum drawdown, and long/short exposure ratios from the portfolio value history accumulated during the execution stage. For back-tests, these metrics are finalized after the `BacktestEngine` completes its daily loop, while live mode displays immediate decision outputs without full historical metric calculation.