TradingAgents/docs/CONTRIBUTING_AGENTS.md

145 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Contributing Custom Agents
This guide explains how to create and register third-party trading agents using the generic agent interface.
## Interface Overview
Every agent implements `BaseAgent.analyze(AgentInput) -> AgentOutput`. This contract ensures agents are interchangeable, composable, and benchmarkable.
## Schemas
### AgentInput
```python
from tradingagents.agents import AgentInput
agent_input = AgentInput(
ticker="AAPL",
date="2025-01-15",
context={
"market_data": "...",
"news": "...",
"fundamentals": "...",
"sentiment": "...",
"technical_indicators": "...",
},
)
```
| Field | Type | Required | Description |
|-----------|------------------|----------|--------------------------------------------------|
| `ticker` | `str` | Yes | Stock ticker symbol |
| `date` | `str` | Yes | Analysis date |
| `context` | `dict[str, str]` | No | Optional data keyed by category (see keys above) |
### AgentOutput
| Field | Type | Required | Description |
|-----------------|-------------------------------------------------------------|----------|--------------------------------|
| `rating` | `"BUY" \| "OVERWEIGHT" \| "HOLD" \| "UNDERWEIGHT" \| "SELL"` | Yes | 5-tier recommendation |
| `confidence` | `float` (0.01.0) | Yes | Confidence in the rating |
| `price_targets` | `PriceTargets \| None` | No | Entry, target, and stop-loss |
| `thesis` | `str` | Yes | One-paragraph investment thesis|
| `risk_factors` | `list[str]` | No | Key risks (defaults to `[]`) |
### PriceTargets
| Field | Type | Description |
|-------------|---------|-------------------|
| `entry` | `float` | Entry price |
| `target` | `float` | Target price |
| `stop_loss` | `float` | Stop-loss price |
## Creating a Custom Agent
Subclass `BaseAgent` and implement `analyze`:
```python
from tradingagents.agents import BaseAgent, AgentInput, AgentOutput
class MyCustomAgent(BaseAgent):
name: str = "my_custom_agent"
def __init__(self, llm) -> None:
self.llm = llm
def analyze(self, agent_input: AgentInput) -> AgentOutput:
# Your analysis logic here — call self.llm, fetch data, etc.
return AgentOutput(
rating="HOLD",
confidence=0.75,
thesis="The stock shows mixed signals...",
risk_factors=["Sector rotation risk", "Earnings uncertainty"],
)
```
The `__init__` signature is flexible — the only hard requirement is that `analyze` accepts `AgentInput` and returns `AgentOutput`.
## Registering Your Agent
Use `AgentRegistry` to make your agent discoverable:
```python
from tradingagents.agents import AgentRegistry
registry = AgentRegistry()
# Register a class (lazy instantiation with kwargs)
registry.register("my_custom", MyCustomAgent, llm=my_llm)
# Or register a pre-built instance
agent = MyCustomAgent(llm=my_llm)
registry.register("my_custom", agent)
# Retrieve and use
agent = registry.get("my_custom")
output = agent.analyze(agent_input)
# List all registered agents
print(registry.list())
```
## Benchmarking Your Agent
Compare your agent across LLM backends:
```python
from tradingagents.agents import (
AgentInput, LLMBackend, benchmark_agent, benchmark_agents,
)
agent_input = AgentInput(ticker="AAPL", date="2025-01-15")
backends = [
LLMBackend(provider="openai", model="gpt-4o"),
LLMBackend(provider="anthropic", model="claude-sonnet-4-20250514"),
LLMBackend(provider="google", model="gemini-2.0-flash"),
]
# Single agent across backends
report = benchmark_agent(MyCustomAgent, agent_input, backends)
# Multiple agents across backends
report = benchmark_agents(
[MyCustomAgent, FundamentalsAgent],
agent_input,
backends,
)
for row in report.summary():
print(row)
```
Each `BenchmarkResult` contains: `agent_name`, `provider`, `model`, `output`, `elapsed_seconds`, and `error` (if any).
## Checklist
Before submitting a PR with a new agent:
- [ ] Subclasses `BaseAgent`
- [ ] Sets a unique `name` class attribute
- [ ] `analyze()` accepts `AgentInput` and returns `AgentOutput`
- [ ] `rating` uses one of the 5 valid tiers
- [ ] `confidence` is between 0.0 and 1.0
- [ ] Agent is importable and added to `__all__` in `tradingagents/agents/__init__.py`