Metadata-Version: 2.4
Name: tradeodds-langchain
Version: 0.1.0
Summary: LangChain tools for the TradeOdds REST API — drop-in agent integrations for quantitative pattern analysis.
Project-URL: Homepage, https://tradeodds.io
Project-URL: Documentation, https://tradeodds.io/api-docs
Project-URL: Repository, https://github.com/cpoly/tradeodds
Project-URL: Issues, https://github.com/cpoly/tradeodds/issues
Author-email: TradeOdds <support@tradeodds.io>
License: MIT
Keywords: agent,langchain,quantitative,tools,tradeodds,trading
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Requires-Dist: langchain-core>=0.3.0
Requires-Dist: pydantic>=2.0
Requires-Dist: tradeodds>=0.1.0
Description-Content-Type: text/markdown

# tradeodds-langchain

LangChain tools for the [TradeOdds](https://tradeodds.io) REST API. Drop the four tools below into any LangChain agent and it can reason about quantitative pattern analysis on ~3,200 symbols.

```bash
pip install tradeodds-langchain
```

## Quickstart

```python
import os
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from tradeodds_langchain import all_tools

os.environ.setdefault("TRADEODDS_API_KEY", "sk-to-...")

tools = all_tools()
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a quantitative trading research assistant. Ground every claim in TradeOdds base rates."),
    ("human", "{input}"),
    ("placeholder", "{agent_scratchpad}"),
])

agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
executor.invoke({"input": "What usually happens in SPY 5 days after a high-VIX bull-regime day?"})
```

## Tools

| Tool | What it does | Auth | Cost |
|---|---|---|---|
| `TradeOddsListSymbolsTool` | List every available symbol (~3,200) | none | free |
| `TradeOddsPriceHistoryTool` | Daily OHLCV bars for a symbol | none | free |
| `TradeOddsAnalyzeTool` | Historical pattern analysis on one symbol | API key | $0.05 |
| `TradeOddsFactorMatchTool` | Scan all symbols for current matches | API key | $0.15 |

Each tool subclasses `langchain_core.tools.BaseTool` with a Pydantic v2 `args_schema`. Tool descriptions are written for the LLM — they explain *what* the tool does, *when* to use it, and *what shape* it returns, so most agents pick the right tool with no extra prompting.

## Configuration

Set `TRADEODDS_API_KEY` in your environment (or pass `client=TradeOddsClient(api_key=...)` per tool). Get a key at <https://tradeodds.io/account>.

## Sharing a client

By default each tool builds its own `TradeOddsClient`. To share an HTTP session (e.g. with retries) across all four tools:

```python
from tradeodds import TradeOddsClient
from tradeodds_langchain import all_tools

client = TradeOddsClient(api_key="sk-to-...", timeout=120.0)
tools = all_tools(client=client)
```

## Manual tool wiring

If you only need one tool, import it directly:

```python
from tradeodds_langchain import TradeOddsFactorMatchTool

tool = TradeOddsFactorMatchTool()
result = tool.invoke({
    "conditions": {"vix_level": True, "regime": True, "rsi_zone": True},
    "filters": {"is_etf": False, "price_min": 10},
    "perf_filter": {"metric": "win_5d", "operator": "gt", "threshold": 0.6},
    "min_instances": 20,
})
```

## Error handling

API errors are returned as a structured dict so the agent can read them:

```python
{"ok": False, "error": {"code": "rate_limit_exceeded", "message": "...", "hint": "...", "request_id": "...", "status_code": 429}}
```

That way one bad call doesn't break an agent loop — the LLM sees the error envelope and can retry, narrow the query, or surface the issue to the user.

## License

MIT.
