Cuatro analistas, un debate alcista/bajista, un trader y un comité de riesgo — orquestados sobre LangGraph
TradingAgents replica la estructura de una firma de inversión real: analistas fundamentales, técnicos, de noticias y de sentimiento; investigadores que debaten a favor y en contra; un trader que propone la operación; y un equipo de riesgo que la aprueba o la tumba. Todo con agentes LLM coordinados mediante un grafo de LangGraph. En este curso instalas el framework, eliges tus modelos, ejecutas análisis completos desde el CLI y desde Python, y entiendes cada engranaje del pipeline.
TradingAgents es un framework open-source (Apache-2.0, ~104.000 estrellas en GitHub) que construye un equipo de analistas de IA capaz de evaluar un activo y emitir una decisión de compra, venta o mantenimiento. No es un bot de trading con reglas fijas: es un sistema donde varios agentes LLM especializados debaten entre sí antes de decidir.
La idea nace de un paper académico (arXiv:2412.20138) y su lema es simple: si una firma de inversión real separa el trabajo en analistas, investigadores, traders y gestores de riesgo, ¿por qué no replicar esa estructura con agentes conversacionales?
El propio proyecto lo declara: está diseñado para investigación, no como consejo financiero. Lo usaremos como banco de pruebas para estudiar sistemas multiagente, no para operar dinero real sin más.
| Dato | Valor |
|---|---|
| Licencia | Apache-2.0 |
| Lenguaje | Python ≥ 3.10 |
| Orquestación | LangGraph |
| Versión actual | 0.4.0 |
| Proveedores LLM | 17+ (OpenAI, Anthropic, Google, DeepSeek, Qwen, GLM, MiniMax, Groq, Mistral, Ollama, Bedrock…) |
TradingAgents no es una cadena lineal de prompts: es un grafo dirigido donde cada nodo es un agente (o un grupo de agentes) y las aristas deciden qué se ejecuta después. El recorrido de una análisis es siempre el mismo:
| Fase | Agentes | Qué produce |
|---|---|---|
| 1. Analistas | Fundamental, Técnico, Noticias, Sentimiento | Cuatro informes independientes sobre el activo |
| 2. Investigadores | Bull (alcista) y Bear (bajista) | Un debate de N rondas que sopesa tesis y riesgos |
| 3. Gestor de investigación | Research Manager | Un plan de inversión consensuado |
| 4. Trader | Trader Agent | Propuesta concreta: dirección, momento y tamaño |
| 5. Riesgo | Agresivo, Conservador, Neutral | Debate sobre volatilidad, liquidez y exposición |
| 6. Decisión | Portfolio Manager | Aprueba o rechaza y emite la orden a la simulación |
Fíjate en el patrón: los analistas recogen evidencia, los investigadores la confrontan y los gestores deciden. Separar esas tres capas es lo que evita que un solo prompt alucine una recomendación sin contraste.
TradingAgents/
├── main.py # script mínimo de ejemplo
├── cli/ # interfaz de terminal (Typer + Rich)
├── tradingagents/
│ ├── default_config.py # TODA la configuración
│ ├── agents/
│ │ ├── analysts/ # fundamental, market, news, sentiment, social
│ │ ├── researchers/ # bull_researcher, bear_researcher
│ │ ├── managers/ # research_manager, portfolio_manager
│ │ ├── risk_mgmt/ # aggressive, conservative, neutral debators
│ │ └── trader/ # trader.py
│ ├── dataflows/ # yfinance, alpha_vantage, fred, polymarket, reddit
│ ├── graph/ # trading_graph.py, propagation, reflection, checkpointer
│ └── llm_clients/ # adaptadores por proveedor
└── tests/
Cada carpeta que ves ahí corresponde a un rol del organigrama. Cuando la ejecución avanza, lo hace nodo a nodo siguiendo ese grafo.
Necesitas Python 3.10 o superior. El proyecto recomienda crear un entorno dedicado para no ensuciar tu instalación global.
Descarga el código fuente desde GitHub.
git clone https://github.com/TauricResearch/TradingAgents.git
cd TradingAgents
Con conda o con venv, pero aíslalo.
conda create -n tradingagents python=3.12
conda activate tradingagents
El pyproject.toml ya declara todo lo necesario: LangGraph, LangChain, yfinance, stockstats, y finance.
pip install .
Copia el fichero de ejemplo y rellena al menos un proveedor LLM.
cp .env.example .env
# edita .env y pon tu clave (por ejemplo DEEPSEEK_API_KEY)
Si prefieres no tocar tu Python, el repo incluye docker-compose.yml: docker compose run --rm tradingagents. Para modelos locales hay un perfil Ollama: docker compose --profile ollama run --rm tradingagents-ollama.
Instalar con pip install tradingagents desde PyPI no es la vía documentada: el proyecto se instala desde el clon local con pip install .. Si obtienes un módulo distinto o desactualizado, revisa que estás dentro de la carpeta del repo.
tradingagents --help
Si aparece la ayuda del CLI, el motor está listo. La primera ejecución real descargará datos de mercado, así que necesitarás conexión a internet.
El motor es agnóstico del modelo. Todo se controla con variables de entorno en el fichero .env, y el framework distingue entre un modelo de razonamiento profundo (deep_think_llm) y otro rápido y barato (quick_think_llm).
| Proveedor | Variable de clave | Uso típico |
|---|---|---|
| DeepSeek | DEEPSEEK_API_KEY | Buena relación calidad/precio para análisis largos |
| OpenAI | OPENAI_API_KEY | Modelos GPT de razonamiento |
| Anthropic | ANTHROPIC_API_KEY | Claude |
GOOGLE_API_KEY | Gemini | |
| Qwen (DashScope) | DASHSCOPE_API_KEY | Endpoints internacional y China |
| GLM (Zhipu) / MiniMax | ZHIPU_API_KEY, MINIMAX_API_KEY | Alternativas asiáticas, global y CN |
| OpenRouter / Groq / Mistral | OPENROUTER_API_KEY, GROQ_API_KEY, MISTRAL_API_KEY | Routers y proveedores rápidos |
| Ollama (local) | — | Sin coste por token, todo en tu máquina |
| OpenAI-compatible | OPENAI_COMPATIBLE_API_KEY | vLLM, LM Studio, llama.cpp, relays |
DEEPSEEK_API_KEY=sk-...
TRADINGAGENTS_LLM_PROVIDER=deepseek
TRADINGAGENTS_DEEP_THINK_LLM=deepseek-reasoner
TRADINGAGENTS_QUICK_THINK_LLM=deepseek-chat
TRADINGAGENTS_OUTPUT_LANGUAGE=Spanish
Las variables que empiezan por TRADINGAGENTS_ sobrescriben la configuración por defecto sin tocar código. Los valores se convierten al tipo del valor original: un true sigue siendo booleano, un 3 sigue siendo entero.
Para el proveedor ollama, el endpoint por defecto es http://localhost:11434/v1. Descarga modelos con ollama pull <nombre> y, si el modelo no aparece en la lista del CLI, selecciona «Custom model ID». También puedes apuntar a un Ollama remoto con OLLAMA_BASE_URL.
No mezcles una backend_url de un proveedor con otro. Si configuras una URL pensada para OpenAI y luego cambias a Gemini, la petición se construye con una ruta incorrecta y falla. Deja backend_url vacío para que cada proveedor use su endpoint natural.
La forma más directa de usar TradingAgents es su interfaz de terminal, construida con Typer para los comandos y Rich para el renderizado en vivo.
tradingagents # comando instalado
python -m cli.main # alternativa: desde el código fuente
Al arrancar verás una pantalla donde eliges ticker, fecha de análisis, proveedor LLM, modelos y profundidad de investigación. Después, el CLI va mostrando los informes a medida que se generan, con el estado de cada agente y el consumo de tokens en tiempo real.
Funciona con cualquier mercado que cubra Yahoo Finance, usando el sufijo del exchange:
| Mercado | Ejemplo de ticker |
|---|---|
| Estados Unidos | AAPL, SPY, NVDA |
| España / Europa (Londres) | AZN.L |
| Hong Kong / Tokio | 0700.HK, 7203.T |
| India | RELIANCE.NS, .BO |
| Canadá / Australia | .TO, .AX |
| China A-shares | 600519.SS, .SZ |
| Cripto | BTC-USD, ETH-USD |
El CLI expone un comando analyze con dos opciones de control de estado:
tradingagents analyze --checkpoint # activa la recuperación tras fallo
tradingagents analyze --clear-checkpoints # borra checkpoints y empieza limpio
Los análisis son largos porque encadenan muchos nodos LLM. Usa --checkpoint para no perder media hora de trabajo si se cae la red a mitad de ejecución: al relanzar verás Resuming from step N.
El CLI es cómodo para explorar, pero el verdadero poder está en programar con el framework. Todo gira en torno a la clase TradingAgentsGraph y su método propagate().
from tradingagents.graph.trading_graph import TradingAgentsGraph
from tradingagents.default_config import DEFAULT_CONFIG
ta = TradingAgentsGraph(debug=True, config=DEFAULT_CONFIG.copy())
# forward propagate
_, decision = ta.propagate("NVDA", "2026-01-15")
print(decision)
propagate() devuelve dos cosas: el estado final del grafo (todos los informes intermedios, debates y razonamientos) y la decisión sintetizada. El estado es oro puro si quieres auditar por qué el sistema llegó a una conclusión.
config = DEFAULT_CONFIG.copy()
config["llm_provider"] = "deepseek"
config["deep_think_llm"] = "deepseek-reasoner" # razonamiento complejo
config["quick_think_llm"] = "deepseek-chat" # tareas rápidas
config["max_debate_rounds"] = 2 # más confrontación bull/bear
ta = TradingAgentsGraph(debug=True, config=config)
_, decision = ta.propagate("NVDA", "2026-01-15")
print(decision)
Crea TradingAgentsGraph una vez y llama a propagate() varias veces para distintos tickers. Así reaprovechas la conexión con el proveedor LLM y el registro de memoria acumulada entre análisis.
| Módulo | Responsabilidad |
|---|---|
graph/trading_graph.py | Construye y expone el grafo de agentes |
graph/propagation.py | Encadena la ejecución de los nodos |
graph/conditional_logic.py | Decide el siguiente nodo (bucles de debate, cierre) |
graph/reflection.py | Genera reflexiones sobre el resultado real |
graph/signal_processing.py | Extrae la señal final (compra/venta/mantener) |
graph/checkpointer.py | Persistencia y limpieza de checkpoints |
Si vas a modificar prompts o añadir un rol nuevo, empieza por graph/setup.py (define los nodos) y agents/schemas.py (define las salidas estructuradas).
tradingagents/default_config.py es la única fuente de verdad de la configuración. Cada clave puede sobrescribirse desde el código o desde una variable de entorno.
| Clave | Variable de entorno | Qué hace |
|---|---|---|
llm_provider | TRADINGAGENTS_LLM_PROVIDER | Proveedor activo (openai, deepseek, ollama…) |
deep_think_llm | TRADINGAGENTS_DEEP_THINK_LLM | Modelo para razonamiento complejo |
quick_think_llm | TRADINGAGENTS_QUICK_THINK_LLM | Modelo para tareas rápidas |
max_debate_rounds | TRADINGAGENTS_MAX_DEBATE_ROUNDS | Rondas del debate alcista/bajista |
max_risk_discuss_rounds | TRADINGAGENTS_MAX_RISK_ROUNDS | Rondas del debate de riesgo |
output_language | TRADINGAGENTS_OUTPUT_LANGUAGE | Idioma de informes y decisión final |
temperature | TRADINGAGENTS_TEMPERATURE | Aleatoriedad de muestreo |
checkpoint_enabled | TRADINGAGENTS_CHECKPOINT_ENABLED | Guarda estado tras cada nodo |
llm_max_retries | TRADINGAGENTS_LLM_MAX_RETRIES | Reintentos ante errores 429 |
max_tokens | TRADINGAGENTS_MAX_TOKENS | Tope de tokens de salida |
benchmark_ticker | TRADINGAGENTS_BENCHMARK_TICKER | Índice de referencia para el alfa |
Por defecto el framework crea una carpeta ~/.tradingagents/ con tres subcarpetas:
~/.tradingagents/
├── logs/ # informes de resultados (TRADINGAGENTS_RESULTS_DIR)
├── cache/ # caché de datos y checkpoints SQLite (TRADINGAGENTS_CACHE_DIR)
└── memory/ # trading_memory.md — el registro de decisiones
La clave output_language controla el idioma de los informes y de la decisión final. Internamente el debate se mantiene en inglés para preservar la calidad de razonamiento del modelo; solo se traduce la salida destinada a ti.
Un valor mal escrito provoca un fallo explícito al arrancar (expected a boolean, got 'treu'), y eso es intencional: el framework prefiere romper en voz alta antes que ejecutar un análisis mal configurado en modo desatendido.
Los agentes no inventan cifras: cada afirmación numérica se apoya en un proveedor de datos configurable. La configuración data_vendors define exactamente qué fuente sirve a cada categoría.
| Categoría | Proveedores | Por defecto |
|---|---|---|
core_stock_apis | yfinance, alpha_vantage | yfinance |
technical_indicators | yfinance, alpha_vantage | yfinance |
fundamental_data | yfinance, alpha_vantage | yfinance |
news_data | yfinance, alpha_vantage | yfinance |
macro_data | fred (requiere clave FRED) | fred |
prediction_markets | polymarket (sin clave) | polymarket |
config["data_vendors"] = {
"core_stock_apis": "yfinance,alpha_vantage", # fallback ordenado
"technical_indicators": "yfinance",
"fundamental_data": "yfinance",
"news_data": "yfinance",
"macro_data": "fred",
"prediction_markets": "polymarket",
}
La cadena que escribes es la cadena exacta que se usa: el framework no redirige silenciosamente a proveedores que no has elegido. Si quieres tolerancia a fallos, lista varios separados por comas y el sistema intentará el siguiente cuando el primero falle.
FRED_API_KEY): datos macro de la Reserva Federal — tipos, inflación, empleo. Clave gratuita en el sitio de FRED.ALPHA_VANTAGE_API_KEY): alternativa para precios, fundamentales e indicadores técnicos.Cuando el sistema evalúa su propio acierto, no mide el retorno bruto: mide el retorno frente a un índice de referencia. El mapa benchmark_map elige el índice automáticamente según el sufijo del ticker.
| Sufijo | Índice de referencia |
|---|---|
| (sin sufijo, EE. UU.) | SPY |
.L (Londres) | ^FTSE |
.T (Tokio) | ^N225 |
.HK (Hong Kong) | ^HSI |
.NS / .BO (India) | ^NSEI / ^BSESN |
.TO / .AX | ^GSPTSE / ^AXJO |
.SS / .SZ (China) | 000001.SS / 399001.SZ |
Si analizas un valor europeo, deja benchmark_ticker en None y el framework usará benchmark_map para comparar contra el índice de su región. Fijarlo a mano solo tiene sentido si quieres forzar una referencia concreta.
Un sistema multiagente serio necesita recordar y sobrevivir a fallos. TradingAgents persiste dos tipos de estado.
Cada ejecución completada añade su decisión a ~/.tradingagents/memory/trading_memory.md. En el siguiente análisis del mismo ticker, el sistema:
Es un bucle de aprendizaje ligero: no reentrena ningún modelo, pero arrastra experiencia entre ejecuciones. La ruta se puede cambiar con TRADINGAGENTS_MEMORY_LOG_PATH.
La recuperación es opt-in mediante --checkpoint. Con ella activa, LangGraph guarda estado tras cada nodo y un fallo no obliga a empezar de cero.
# CLI
tradingagents analyze --checkpoint
# Python
config = DEFAULT_CONFIG.copy()
config["checkpoint_enabled"] = True
ta = TradingAgentsGraph(config=config)
Las bases SQLite por ticker viven en ~/.tradingagents/cache/checkpoints/<TICKER>.db y se limpian solas al terminar con éxito. Para forzar un arranque limpio: tradingagents analyze --clear-checkpoints.
Dos análisis del mismo ticker y fecha pueden diferir, y eso no es un bug: el muestreo de los LLM no es determinista y las noticias y redes sociales cambian con el tiempo. Bajar temperature reduce la variación en modelos que la respetan, pero los modelos de razonamiento la ignoran en gran medida.
| Fuente de variación | Se puede fijar |
|---|---|
| Muestreo del modelo | Parcialmente (temperatura) |
| Noticias, StockTwits y Reddit | No — reflejan el «ahora» |
| Fecha de análisis | Sí — fija la ventana de precios e indicadores |
| Identidad de la empresa | Sí — se resuelve de forma determinista desde el ticker |
Llegados aquí sabes montar la firma completa. Ahora la parte que separa un experimento interesante de un malentendido peligroso.
TradingAgents está diseñado para investigación, no para operar capital real. Trátalo como un banco de pruebas para estudiar sistemas multiagente, no como una estrategia con un retorno replicable.
| Práctica | Por qué |
|---|---|
Usa siempre --checkpoint | Los análisis son largos y caros; no pierdas el progreso |
| Empieza con un modelo barato | Valida el pipeline antes de gastar en razonamiento profundo |
| Fija la fecha de análisis | Aísla el efecto de la ventana de precios |
Sube llm_max_retries | Sobrevive a picos de errores 429 en proveedores limitados |
Limita max_tokens | Evita modelos que divagan y cuelgan la ejecución |
| Revisa el estado, no solo la decisión | El razonamiento intermedio es donde está el aprendizaje |
Con la base montada, los siguientes pasos son: añadir un analista propio en agents/analysts/, conectar un proveedor de datos distinto en dataflows/, o envolver propagate() en tu propio servicio para analizar una cartera entera de forma programada.
No necesariamente: puedes ejecutar todo con Ollama en local y sin coste por token. Para datos macro de la Reserva Federal solo necesitas una clave gratuita de FRED, y las cotizaciones vienen de yfinance sin clave.
Depende del proveedor, del modelo y de las rondas de debate configuradas. Encadena bastantes llamadas LLM, por eso conviene activar --checkpoint para poder reanudar si algo falla a mitad.
Sí. Cualquier mercado que cubra Yahoo Finance funciona con el sufijo del exchange (por ejemplo AZN.L para Londres), y el framework detecta automáticamente el índice de referencia regional para calcular el alfa.
No. Un bot ejecuta reglas fijas; aquí un equipo de agentes LLM investiga, debate y decide, y la ejecución ocurre en un entorno simulado. Está pensado para investigación, no para operar capital real.