Skip to the page
INTEGRATIONS/LANGGRAPH

LangGraph

tradefloor.integrations.langgraph wraps any compiled LangGraph graph. The adapter runs your agent inside a simulated market on your machine. tradefloor sends it a JSON observation each decision, checks the decision it returns, places its orders in the simulation and scores the run. LLM adapters covers what every adapter shares: the observation payload and decisions and model calls.

Install

pip install "tradefloor[langgraph]"

A first run

The block runs with no API key, because the graph's one node is a rule in place of a model.

The adapter takes any compiled graph. By default it sends the payload under observation and as messages, and reads the decision from a decision key, an actions key or the last message.

from typing import Any, TypedDict

import tradefloor as tf
from langgraph.graph import END, START, StateGraph
from tradefloor.integrations.langgraph import LangGraphAdapter

class State(TypedDict, total=False):
    observation: dict[str, Any]
    decision: dict[str, Any]

def decide(state: State) -> State:
    # a rule in place of a model: buy 200 of the first name when flat
    first = state["observation"]["assets"][0]
    if first["position"] > 0:
        return {"decision": {"actions": [], "rationale": "holding"}}
    order = {"symbol": first["symbol"], "side": "BUY", "quantity": 200}
    return {"decision": {"actions": [order], "rationale": "open"}}

builder = StateGraph(State)
builder.add_node("decide", decide)
builder.add_edge(START, "decide")
builder.add_edge("decide", END)
adapter = LangGraphAdapter(builder.compile())

market = tf.Universe.random(12, seed=4242)
card = tf.evaluate({"graph": adapter}, seed=4242, universe=market, days=5)["graph"]
print(card)
print(len(adapter.record), "decisions")
Scorecard('graph', pnl=544, return=+0.05%, trades=1, impact=+0.04bps, sharpe=n/a (short run), vol=0.1%, in_market=100%, exposure=0.01x)
5 decisions

A node that calls a model makes the graph live, and nothing else changes. The graph decides five times and trades once, because after the first day it holds the name and answers with an empty action list, which is a decision to change nothing.

Tested with

langgraph 1.2.12 and tradefloor 0.9.1.